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
obj.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__ 0x0F 00011 00012 00013 /** 00014 * \file 00015 * \brief Object Type 00016 * 00017 * Object type operations. 00018 */ 00019 00020 00021 #include "pm.h" 00022 00023 00024 PmReturn_t 00025 obj_loadFromImg(PmMemSpace_t memspace, 00026 uint8_t const **paddr, pPmObj_t *r_pobj) 00027 { 00028 PmReturn_t retval = PM_RET_OK; 00029 PmObj_t obj; 00030 00031 00032 /* Get the object descriptor */ 00033 obj.od = (PmObjDesc_t)0x0000; 00034 OBJ_SET_TYPE(&obj, mem_getByte(memspace, paddr)); 00035 00036 switch (OBJ_GET_TYPE(&obj)) 00037 { 00038 case OBJ_TYPE_NON: 00039 /* If it's the None object, return global None */ 00040 *r_pobj = PM_NONE; 00041 break; 00042 00043 case OBJ_TYPE_INT: 00044 /* Read an integer and create an integer object with the value */ 00045 retval = int_new(mem_getInt(memspace, paddr), r_pobj); 00046 break; 00047 00048 #ifdef HAVE_FLOAT 00049 case OBJ_TYPE_FLT: 00050 /* Read a float and create an float object with the value */ 00051 retval = float_new(mem_getFloat(memspace, paddr), r_pobj); 00052 break; 00053 #endif /* HAVE_FLOAT */ 00054 00055 case OBJ_TYPE_STR: 00056 retval = string_loadFromImg(memspace, paddr, r_pobj); 00057 break; 00058 00059 case OBJ_TYPE_TUP: 00060 retval = tuple_loadFromImg(memspace, paddr, r_pobj); 00061 break; 00062 00063 case OBJ_TYPE_NIM: 00064 /* If it's a native code img, load into a code obj */ 00065 retval = no_loadFromImg(memspace, paddr, r_pobj); 00066 break; 00067 00068 case OBJ_TYPE_CIM: 00069 /* If it's a code img, load into a code obj */ 00070 retval = co_loadFromImg(memspace, paddr, r_pobj); 00071 break; 00072 00073 default: 00074 /* All other types should not be in an img obj */ 00075 PM_RAISE(retval, PM_RET_EX_SYS); 00076 break; 00077 } 00078 return retval; 00079 } 00080 00081 00082 PmReturn_t 00083 obj_loadFromImgObj(pPmObj_t pimg, pPmObj_t *r_pobj) 00084 { 00085 uint8_t const *imgaddr; 00086 PmReturn_t retval; 00087 00088 C_ASSERT(OBJ_GET_TYPE(pimg) == OBJ_TYPE_CIO); 00089 imgaddr = (uint8_t const *)&(((pPmCodeImgObj_t)pimg)->val); 00090 00091 retval = obj_loadFromImg(MEMSPACE_RAM, &imgaddr, r_pobj); 00092 C_ASSERT(OBJ_GET_TYPE(*r_pobj) == OBJ_TYPE_COB); 00093 00094 /* All COs must reference the top of the code img obj 00095 * so the image is marked and prevented from being reclaimed */ 00096 co_rSetCodeImgAddr((pPmCo_t)*r_pobj, (uint8_t const *)pimg); 00097 00098 return retval; 00099 } 00100 00101 00102 /* Returns true if the obj is false */ 00103 int8_t 00104 obj_isFalse(pPmObj_t pobj) 00105 { 00106 C_ASSERT(pobj != C_NULL); 00107 00108 switch (OBJ_GET_TYPE(pobj)) 00109 { 00110 case OBJ_TYPE_NON: 00111 /* None evaluates to false, so return true */ 00112 return C_TRUE; 00113 00114 case OBJ_TYPE_INT: 00115 /* Only the integer zero is false */ 00116 return ((pPmInt_t)pobj)->val == 0; 00117 00118 #ifdef HAVE_FLOAT 00119 case OBJ_TYPE_FLT: 00120 /* The floats 0.0 and -0.0 are false */ 00121 return (((pPmFloat_t) pobj)->val == 0.0) 00122 || (((pPmFloat_t) pobj)->val == -0.0); 00123 #endif /* HAVE_FLOAT */ 00124 00125 case OBJ_TYPE_STR: 00126 /* An empty string is false */ 00127 return ((pPmString_t)pobj)->length == 0; 00128 00129 case OBJ_TYPE_TUP: 00130 /* An empty tuple is false */ 00131 return ((pPmTuple_t)pobj)->length == 0; 00132 00133 case OBJ_TYPE_LST: 00134 /* An empty list is false */ 00135 return ((pPmList_t)pobj)->length == 0; 00136 00137 case OBJ_TYPE_DIC: 00138 /* An empty dict is false */ 00139 return ((pPmDict_t)pobj)->length == 0; 00140 00141 case OBJ_TYPE_BOOL: 00142 /* C int zero means false */ 00143 return ((pPmBoolean_t) pobj)->val == 0; 00144 00145 default: 00146 /* 00147 * The following types are always not false: 00148 * CodeObj, Function, Module, Class, ClassInstance. 00149 */ 00150 return C_FALSE; 00151 } 00152 } 00153 00154 00155 /* Returns true if the item is in the container object */ 00156 PmReturn_t 00157 obj_isIn(pPmObj_t pobj, pPmObj_t pitem) 00158 { 00159 PmReturn_t retval = PM_RET_NO; 00160 pPmObj_t ptestItem; 00161 int16_t i; 00162 uint8_t c; 00163 00164 switch (OBJ_GET_TYPE(pobj)) 00165 { 00166 case OBJ_TYPE_TUP: 00167 /* Iterate over tuple to find item */ 00168 for (i = 0; i < ((pPmTuple_t)pobj)->length; i++) 00169 { 00170 PM_RETURN_IF_ERROR(tuple_getItem(pobj, i, &ptestItem)); 00171 00172 if (obj_compare(pitem, ptestItem) == C_SAME) 00173 { 00174 retval = PM_RET_OK; 00175 break; 00176 } 00177 } 00178 break; 00179 00180 case OBJ_TYPE_STR: 00181 /* Raise a TypeError if item is not a string */ 00182 if ((OBJ_GET_TYPE(pitem) != OBJ_TYPE_STR)) 00183 { 00184 retval = PM_RET_EX_TYPE; 00185 break; 00186 } 00187 00188 /* Empty string is alway present */ 00189 if (((pPmString_t)pitem)->length == 0) 00190 { 00191 retval = PM_RET_OK; 00192 break; 00193 } 00194 00195 /* Raise a ValueError if the string is more than 1 char */ 00196 else if (((pPmString_t)pitem)->length != 1) 00197 { 00198 retval = PM_RET_EX_VAL; 00199 break; 00200 } 00201 00202 /* Iterate over string to find char */ 00203 c = ((pPmString_t)pitem)->val[0]; 00204 for (i = 0; i < ((pPmString_t)pobj)->length; i++) 00205 { 00206 if (c == ((pPmString_t)pobj)->val[i]) 00207 { 00208 retval = PM_RET_OK; 00209 break; 00210 } 00211 } 00212 break; 00213 00214 case OBJ_TYPE_LST: 00215 /* Iterate over list to find item */ 00216 for (i = 0; i < ((pPmList_t)pobj)->length; i++) 00217 { 00218 PM_RETURN_IF_ERROR(list_getItem(pobj, i, &ptestItem)); 00219 00220 if (obj_compare(pitem, ptestItem) == C_SAME) 00221 { 00222 retval = PM_RET_OK; 00223 break; 00224 } 00225 } 00226 break; 00227 00228 case OBJ_TYPE_DIC: 00229 /* Check if the item is one of the keys of the dict */ 00230 retval = dict_getItem(pobj, pitem, &ptestItem); 00231 if (retval == PM_RET_EX_KEY) 00232 { 00233 retval = PM_RET_NO; 00234 } 00235 break; 00236 00237 default: 00238 retval = PM_RET_EX_TYPE; 00239 break; 00240 } 00241 00242 return retval; 00243 } 00244 00245 00246 int8_t 00247 obj_compare(pPmObj_t pobj1, pPmObj_t pobj2) 00248 { 00249 #ifdef HAVE_BYTEARRAY 00250 PmReturn_t retval; 00251 pPmObj_t pobj; 00252 #endif /* HAVE_BYTEARRAY */ 00253 00254 C_ASSERT(pobj1 != C_NULL); 00255 C_ASSERT(pobj2 != C_NULL); 00256 00257 /* Check if pointers are same */ 00258 if (pobj1 == pobj2) 00259 { 00260 return C_SAME; 00261 } 00262 00263 /* If types are different, objs must differ */ 00264 if (OBJ_GET_TYPE(pobj1) != OBJ_GET_TYPE(pobj2)) 00265 { 00266 return C_DIFFER; 00267 } 00268 00269 #ifdef HAVE_BYTEARRAY 00270 /* If object is an instance, get the thing it contains */ 00271 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLI) 00272 { 00273 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj1)->cli_attrs, 00274 PM_NONE, 00275 &pobj); 00276 PM_RETURN_IF_ERROR(retval); 00277 pobj1 = pobj; 00278 } 00279 if (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_CLI) 00280 { 00281 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj2)->cli_attrs, 00282 PM_NONE, 00283 &pobj); 00284 PM_RETURN_IF_ERROR(retval); 00285 pobj2 = pobj; 00286 } 00287 00288 /* If types are different, objs must differ */ 00289 if (OBJ_GET_TYPE(pobj1) != OBJ_GET_TYPE(pobj2)) 00290 { 00291 return C_DIFFER; 00292 } 00293 #endif /* HAVE_BYTEARRAY */ 00294 00295 /* Otherwise handle types individually */ 00296 switch (OBJ_GET_TYPE(pobj1)) 00297 { 00298 case OBJ_TYPE_NON: 00299 return C_SAME; 00300 00301 case OBJ_TYPE_INT: 00302 return ((pPmInt_t)pobj1)->val == 00303 ((pPmInt_t)pobj2)->val ? C_SAME : C_DIFFER; 00304 00305 #ifdef HAVE_FLOAT 00306 case OBJ_TYPE_FLT: 00307 { 00308 pPmObj_t r_pobj; 00309 00310 float_compare(pobj1, pobj2, &r_pobj, COMP_EQ); 00311 return (r_pobj == PM_TRUE) ? C_SAME : C_DIFFER; 00312 } 00313 #endif /* HAVE_FLOAT */ 00314 00315 case OBJ_TYPE_STR: 00316 return string_compare((pPmString_t)pobj1, (pPmString_t)pobj2); 00317 00318 case OBJ_TYPE_TUP: 00319 case OBJ_TYPE_LST: 00320 #ifdef HAVE_BYTEARRAY 00321 case OBJ_TYPE_BYA: 00322 #endif /* HAVE_BYTEARRAY */ 00323 return seq_compare(pobj1, pobj2); 00324 00325 case OBJ_TYPE_DIC: 00326 return dict_compare(pobj1, pobj2); 00327 00328 default: 00329 break; 00330 } 00331 00332 /* All other types would need same pointer to be true */ 00333 return C_DIFFER; 00334 } 00335 00336 00337 #ifdef HAVE_PRINT 00338 PmReturn_t 00339 obj_print(pPmObj_t pobj, uint8_t is_expr_repr, uint8_t is_nested) 00340 { 00341 PmReturn_t retval = PM_RET_OK; 00342 00343 C_ASSERT(pobj != C_NULL); 00344 00345 /* Something gets printed unless it's None in an unnested expression */ 00346 if (!((OBJ_GET_TYPE(pobj) == OBJ_TYPE_NON) && is_expr_repr && !is_nested)) 00347 { 00348 gVmGlobal.somethingPrinted = C_TRUE; 00349 } 00350 00351 switch (OBJ_GET_TYPE(pobj)) 00352 { 00353 case OBJ_TYPE_NON: 00354 if (!is_expr_repr || is_nested) 00355 { 00356 sli_puts((uint8_t *)"None"); 00357 } 00358 break; 00359 case OBJ_TYPE_INT: 00360 retval = int_print(pobj); 00361 break; 00362 #ifdef HAVE_FLOAT 00363 case OBJ_TYPE_FLT: 00364 retval = float_print(pobj); 00365 break; 00366 #endif /* HAVE_FLOAT */ 00367 case OBJ_TYPE_STR: 00368 retval = string_print(pobj, (is_expr_repr || is_nested)); 00369 break; 00370 case OBJ_TYPE_TUP: 00371 retval = tuple_print(pobj); 00372 break; 00373 case OBJ_TYPE_LST: 00374 retval = list_print(pobj); 00375 break; 00376 case OBJ_TYPE_DIC: 00377 retval = dict_print(pobj); 00378 break; 00379 case OBJ_TYPE_BOOL: 00380 sli_puts( 00381 (((pPmBoolean_t) pobj)->val == C_TRUE) 00382 ? (uint8_t *)"True" 00383 : (uint8_t *)"False"); 00384 break; 00385 00386 case OBJ_TYPE_CLI: 00387 #ifdef HAVE_BYTEARRAY 00388 { 00389 pPmObj_t pobj2; 00390 00391 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, 00392 PM_NONE, 00393 (pPmObj_t *)&pobj2); 00394 if ((retval == PM_RET_OK) 00395 && (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_BYA)) 00396 { 00397 retval = bytearray_print(pobj2); 00398 break; 00399 } 00400 } 00401 #endif /* HAVE_BYTEARRAY */ 00402 00403 case OBJ_TYPE_COB: 00404 case OBJ_TYPE_MOD: 00405 case OBJ_TYPE_CLO: 00406 case OBJ_TYPE_FXN: 00407 case OBJ_TYPE_CIM: 00408 case OBJ_TYPE_NIM: 00409 case OBJ_TYPE_NOB: 00410 case OBJ_TYPE_THR: 00411 case OBJ_TYPE_CIO: 00412 case OBJ_TYPE_MTH: 00413 case OBJ_TYPE_SQI: 00414 { 00415 uint8_t buf[17]; 00416 sli_puts((uint8_t *)"<obj type 0x"); 00417 sli_btoa16(OBJ_GET_TYPE(pobj), buf, sizeof(buf), C_TRUE); 00418 sli_puts(buf); 00419 sli_puts((uint8_t *)" @ 0x"); 00420 sli_ptoa16((intptr_t)pobj, buf, sizeof(buf), C_TRUE); 00421 sli_puts(buf); 00422 retval = plat_putByte('>'); 00423 break; 00424 } 00425 00426 default: 00427 /* Otherwise raise a TypeError */ 00428 PM_RAISE(retval, PM_RET_EX_TYPE); 00429 break; 00430 } 00431 return retval; 00432 } 00433 #endif /* HAVE_PRINT */ 00434 00435 00436 #ifdef HAVE_BACKTICK 00437 PmReturn_t 00438 obj_repr(pPmObj_t pobj, pPmObj_t *r_pstr) 00439 { 00440 uint8_t tBuffer[32]; 00441 PmReturn_t retval = PM_RET_OK; 00442 uint8_t const *pcstr = (uint8_t *)tBuffer;; 00443 00444 C_ASSERT(pobj != C_NULL); 00445 00446 switch (OBJ_GET_TYPE(pobj)) 00447 { 00448 case OBJ_TYPE_INT: 00449 retval = sli_ltoa10(((pPmInt_t)pobj)->val, tBuffer, sizeof(tBuffer)); 00450 PM_RETURN_IF_ERROR(retval); 00451 retval = string_new(&pcstr, r_pstr); 00452 break; 00453 00454 #ifdef HAVE_FLOAT 00455 case OBJ_TYPE_FLT: 00456 /* #212: Use homebrew float formatter */ 00457 retval = sli_ftoa(((pPmFloat_t)pobj)->val, tBuffer, sizeof(tBuffer)); 00458 sli_strlen((char *)tBuffer); 00459 retval = string_new(&pcstr, r_pstr); 00460 break; 00461 #endif /* HAVE_FLOAT */ 00462 00463 default: 00464 /* Otherwise raise a TypeError */ 00465 PM_RAISE(retval, PM_RET_EX_TYPE); 00466 break; 00467 } 00468 00469 return retval; 00470 } 00471 #endif /* HAVE_BACKTICK */
Generated on Tue Jul 12 2022 21:25:46 by
1.7.2
