tuple.c

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

Generated on Mon Oct 18 07:40:48 2010 for Python-on-a-chip by  doxygen 1.5.9