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.
tuple.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__ 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 */
Generated on Tue Jul 12 2022 23:13:47 by
1.7.2