davide carboni / Mbed 2 deprecated pymite_http_get

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers obj.c Source File

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