python-on-a-chip online compiler

Dependencies:   mbed TSI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tuple.c Source File

tuple.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__ 0x13
00011 
00012 
00013 /**
00014  * \file
00015  * \brief Tuple Object Type
00016  *
00017  * Tuple object type operations.
00018  */
00019 
00020 
00021 #include "pm.h"
00022 
00023 
00024 /* The follwing value should match that in pmImgCreator.py */
00025 #define MAX_TUPLE_LEN 253
00026 
00027 
00028 PmReturn_t
00029 tuple_loadFromImg(PmMemSpace_t memspace,
00030                   uint8_t const **paddr, pPmObj_t *r_ptuple)
00031 {
00032     PmReturn_t retval = PM_RET_OK;
00033     uint8_t i = (uint8_t)0;
00034     uint8_t n = (uint8_t)0;
00035     uint8_t objid;
00036 
00037     /* Get num objs in tuple */
00038     n = mem_getByte(memspace, paddr);
00039 
00040     /* Create empty tuple */
00041     retval = tuple_new(n, r_ptuple);
00042     PM_RETURN_IF_ERROR(retval);
00043     ((pPmTuple_t)*r_ptuple)->length = 0;
00044 
00045     /* Load the next n objs into tuple */
00046     heap_gcPushTempRoot((pPmObj_t)*r_ptuple, &objid);
00047     for (i = (uint8_t)0; i < n; i++)
00048     {
00049         retval = obj_loadFromImg(memspace,
00050                                  paddr,
00051                                  (pPmObj_t *)&(((pPmTuple_t)*r_ptuple)->
00052                                                val[i]));
00053         if (retval != PM_RET_OK)
00054         {
00055             heap_gcPopTempRoot(objid);
00056             return retval;
00057         }
00058         ((pPmTuple_t)*r_ptuple)->length++;
00059     }
00060     heap_gcPopTempRoot(objid);
00061     return PM_RET_OK;
00062 }
00063 
00064 
00065 PmReturn_t
00066 tuple_new(uint16_t n, pPmObj_t *r_ptuple)
00067 {
00068     PmReturn_t retval = PM_RET_OK;
00069     uint16_t size = 0;
00070 
00071     /* Raise a SystemError for a Tuple that is too large */
00072     if (n > MAX_TUPLE_LEN)
00073     {
00074         PM_RAISE(retval, PM_RET_EX_SYS);
00075         return retval;
00076     }
00077 
00078     /* Calc size of struct to hold tuple; (n-1) because PmTuple_t has val[1] */
00079     size = sizeof(PmTuple_t) + ((n - 1) * sizeof(pPmObj_t));
00080 
00081     /* Allocate a tuple */
00082     retval = heap_getChunk(size, (uint8_t **)r_ptuple);
00083     PM_RETURN_IF_ERROR(retval);
00084     OBJ_SET_TYPE(*r_ptuple, OBJ_TYPE_TUP);
00085 
00086     /* Set the number of objs in the tuple */
00087     ((pPmTuple_t)*r_ptuple)->length = n;
00088 
00089     /* Clear entries in the tuple so the GC doesn't try to mark/sweep them */
00090     if (n > 0)
00091     {
00092         size = n;
00093         while (--size > 0)
00094         {
00095             ((pPmTuple_t)*r_ptuple)->val[size] = C_NULL;
00096         }
00097     }
00098 
00099     /* No need to null the ptrs because they are set by the caller */
00100     return retval;
00101 }
00102 
00103 
00104 PmReturn_t
00105 tuple_replicate(pPmObj_t ptup, int16_t n, pPmObj_t *r_ptuple)
00106 {
00107     PmReturn_t retval = PM_RET_OK;
00108     int16_t length;
00109     int16_t i;
00110     int16_t j;
00111 
00112     /* Raise TypeError if object is not a Tuple */
00113     if (OBJ_GET_TYPE(ptup) != OBJ_TYPE_TUP)
00114     {
00115         PM_RAISE(retval, PM_RET_EX_SYS);
00116         return retval;
00117     }
00118 
00119     C_ASSERT(n >= 0);
00120 
00121     /* Allocate the new tuple */
00122     length = ((pPmTuple_t)ptup)->length;
00123     retval = tuple_new(length * n, r_ptuple);
00124     PM_RETURN_IF_ERROR(retval);
00125 
00126     /* Copy src tuple the designated number of times */
00127     for (i = 0; i < n; i++)
00128     {
00129         for (j = 0; j < length; j++)
00130         {
00131             ((pPmTuple_t)*r_ptuple)->val[length * i + j] =
00132                 ((pPmTuple_t)ptup)->val[j];
00133         }
00134     }
00135     return retval;
00136 }
00137 
00138 
00139 PmReturn_t
00140 tuple_getItem(pPmObj_t ptup, int16_t index, pPmObj_t *r_pobj)
00141 {
00142     PmReturn_t retval = PM_RET_OK;
00143 
00144     /* Adjust for negative index */
00145     if (index < 0)
00146     {
00147         index += ((pPmTuple_t)ptup)->length;
00148     }
00149 
00150     /* Raise IndexError if index is out of bounds */
00151     if ((index < 0) || (index > ((pPmTuple_t)ptup)->length))
00152     {
00153         PM_RAISE(retval, PM_RET_EX_INDX);
00154     }
00155 
00156     /* Get the tuple item */
00157     *r_pobj = ((pPmTuple_t)ptup)->val[index];
00158 
00159     return retval;
00160 }
00161 
00162 
00163 #ifdef HAVE_PRINT
00164 PmReturn_t
00165 tuple_print(pPmObj_t ptup)
00166 {
00167     PmReturn_t retval = PM_RET_OK;
00168     int16_t index;
00169 
00170     C_ASSERT(ptup != C_NULL);
00171 
00172     /* If it's not a tuple, raise TypeError */
00173     if (OBJ_GET_TYPE(ptup) != OBJ_TYPE_TUP)
00174     {
00175         PM_RAISE(retval, PM_RET_EX_TYPE);
00176         return retval;
00177     }
00178 
00179     plat_putByte('(');
00180 
00181     for (index = 0; index < ((pPmTuple_t)ptup)->length; index++)
00182     {
00183         if (index != 0)
00184         {
00185             plat_putByte(',');
00186             plat_putByte(' ');
00187         }
00188         retval = obj_print(((pPmTuple_t)ptup)->val[index], C_FALSE, C_TRUE);
00189         PM_RETURN_IF_ERROR(retval);
00190     }
00191 
00192     return plat_putByte(')');
00193 }
00194 #endif /* HAVE_PRINT */