Norimasa Okamoto
/
pymite
python-on-a-chip online compiler
Embed:
(wiki syntax)
Show/hide line numbers
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 */
Generated on Tue Jul 12 2022 23:13:47 by 1.7.2