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.
seq.c
00001 /* 00002 # This file is Copyright 2006 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__ 0x14 00011 00012 00013 /** 00014 * \file 00015 * \brief Sequence 00016 * 00017 * Functions that operate on sequences 00018 */ 00019 00020 00021 #include "pm.h" 00022 00023 00024 /* 00025 * Compares two sequence objects 00026 * Assumes both objects are of same type (guaranteed by obj_compare) 00027 */ 00028 int8_t 00029 seq_compare(pPmObj_t pobj1, pPmObj_t pobj2) 00030 { 00031 int16_t l1; 00032 int16_t l2; 00033 pPmObj_t pa; 00034 pPmObj_t pb; 00035 PmReturn_t retval; 00036 int8_t retcompare; 00037 00038 /* Get the lengths of supported types or return differ */ 00039 if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_TUP) 00040 { 00041 l1 = ((pPmTuple_t)pobj1)->length; 00042 l2 = ((pPmTuple_t)pobj2)->length; 00043 } 00044 else if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_LST) 00045 { 00046 l1 = ((pPmList_t)pobj1)->length; 00047 l2 = ((pPmList_t)pobj2)->length; 00048 } 00049 00050 #ifdef HAVE_BYTEARRAY 00051 else if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_BYA) 00052 { 00053 /* Return if the lengths differ */ 00054 l1 = ((pPmBytearray_t)pobj1)->length; 00055 l2 = ((pPmBytearray_t)pobj2)->length; 00056 if (l1 != l2) 00057 { 00058 return C_DIFFER; 00059 } 00060 00061 return sli_strncmp((char const *)&(((pPmBytes_t)((pPmBytearray_t)pobj1)->val)->val), 00062 (char const *)&(((pPmBytes_t)((pPmBytearray_t)pobj2)->val)->val), 00063 l1) 00064 ? C_DIFFER : C_SAME; 00065 } 00066 #endif /* HAVE_BYTEARRAY */ 00067 00068 else 00069 { 00070 return C_DIFFER; 00071 } 00072 00073 /* Return if the lengths differ */ 00074 if (l1 != l2) 00075 { 00076 return C_DIFFER; 00077 } 00078 00079 /* Compare all items in the sequences */ 00080 while (--l1 >= 0) 00081 { 00082 retval = seq_getSubscript(pobj1, l1, &pa); 00083 if (retval != PM_RET_OK) 00084 { 00085 return C_DIFFER; 00086 } 00087 retval = seq_getSubscript(pobj2, l1, &pb); 00088 if (retval != PM_RET_OK) 00089 { 00090 return C_DIFFER; 00091 } 00092 retcompare = obj_compare(pa, pb); 00093 if (retcompare != C_SAME) 00094 { 00095 return retcompare; 00096 } 00097 } 00098 00099 return C_SAME; 00100 } 00101 00102 00103 /* Returns the length of the sequence */ 00104 PmReturn_t 00105 seq_getLength(pPmObj_t pobj, uint16_t *r_index) 00106 { 00107 PmReturn_t retval = PM_RET_OK; 00108 00109 switch (OBJ_GET_TYPE(pobj)) 00110 { 00111 case OBJ_TYPE_STR: 00112 *r_index = ((pPmString_t)pobj)->length; 00113 break; 00114 00115 case OBJ_TYPE_TUP: 00116 *r_index = ((pPmTuple_t)pobj)->length; 00117 break; 00118 00119 case OBJ_TYPE_LST: 00120 *r_index = ((pPmList_t)pobj)->length; 00121 break; 00122 00123 #ifdef HAVE_BYTEARRAY 00124 case OBJ_TYPE_BYA: 00125 *r_index = ((pPmBytearray_t)pobj)->length; 00126 break; 00127 #endif /* HAVE_BYTEARRAY */ 00128 00129 case OBJ_TYPE_DIC: 00130 *r_index = ((pPmDict_t)pobj)->length; 00131 break; 00132 00133 default: 00134 /* Raise TypeError, non-sequence object */ 00135 PM_RAISE(retval, PM_RET_EX_TYPE); 00136 break; 00137 } 00138 00139 return retval; 00140 } 00141 00142 00143 /* Returns the object sequence[index] */ 00144 PmReturn_t 00145 seq_getSubscript(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj) 00146 { 00147 PmReturn_t retval; 00148 pSeglist_t pkeys; 00149 uint8_t c; 00150 00151 switch (OBJ_GET_TYPE(pobj)) 00152 { 00153 case OBJ_TYPE_STR: 00154 /* Adjust for negative index */ 00155 if (index < 0) 00156 { 00157 index += ((pPmString_t)pobj)->length; 00158 } 00159 00160 /* Raise IndexError if index is out of bounds */ 00161 if ((index < 0) || (index > ((pPmString_t)pobj)->length)) 00162 { 00163 PM_RAISE(retval, PM_RET_EX_INDX); 00164 break; 00165 } 00166 00167 /* Get the character from the string */ 00168 c = ((pPmString_t)pobj)->val[index]; 00169 00170 /* Create a new string from the character */ 00171 retval = string_newFromChar(c, r_pobj); 00172 break; 00173 00174 case OBJ_TYPE_TUP: 00175 /* Get the tuple item */ 00176 retval = tuple_getItem(pobj, index, r_pobj); 00177 break; 00178 00179 case OBJ_TYPE_LST: 00180 /* Get the list item */ 00181 retval = list_getItem(pobj, index, r_pobj); 00182 break; 00183 00184 #ifdef HAVE_BYTEARRAY 00185 case OBJ_TYPE_BYA: 00186 retval = bytearray_getItem(pobj, index, r_pobj); 00187 break; 00188 #endif /* HAVE_BYTEARRAY */ 00189 00190 /* Issue #176 Add support to iterate over keys in a dict */ 00191 case OBJ_TYPE_DIC: 00192 pkeys = ((pPmDict_t)pobj)->d_keys; 00193 retval = seglist_getItem(pkeys, index, r_pobj); 00194 break; 00195 00196 default: 00197 /* Raise TypeError, unsubscriptable object */ 00198 PM_RAISE(retval, PM_RET_EX_TYPE); 00199 break; 00200 } 00201 00202 return retval; 00203 } 00204 00205 00206 PmReturn_t 00207 seqiter_getNext(pPmObj_t pobj, pPmObj_t *r_pitem) 00208 { 00209 PmReturn_t retval; 00210 uint16_t length; 00211 00212 C_ASSERT(pobj != C_NULL); 00213 C_ASSERT(*r_pitem != C_NULL); 00214 C_ASSERT(OBJ_GET_TYPE(pobj) == OBJ_TYPE_SQI); 00215 00216 /* 00217 * Raise TypeError if sequence iterator's object is not a sequence 00218 * otherwise, the get sequence's length 00219 */ 00220 retval = seq_getLength(((pPmSeqIter_t)pobj)->si_sequence, &length); 00221 PM_RETURN_IF_ERROR(retval); 00222 00223 /* Raise StopIteration if at the end of the sequence */ 00224 if (((pPmSeqIter_t)pobj)->si_index == length) 00225 { 00226 /* Make null the pointer to the sequence */ 00227 ((pPmSeqIter_t)pobj)->si_sequence = C_NULL; 00228 PM_RAISE(retval, PM_RET_EX_STOP); 00229 return retval; 00230 } 00231 00232 /* Get the item at the current index */ 00233 retval = seq_getSubscript(((pPmSeqIter_t)pobj)->si_sequence, 00234 ((pPmSeqIter_t)pobj)->si_index, r_pitem); 00235 00236 /* Increment the index */ 00237 ((pPmSeqIter_t)pobj)->si_index++; 00238 00239 return retval; 00240 } 00241 00242 00243 PmReturn_t 00244 seqiter_new(pPmObj_t pobj, pPmObj_t *r_pobj) 00245 { 00246 PmReturn_t retval; 00247 uint8_t *pchunk; 00248 pPmSeqIter_t psi; 00249 00250 C_ASSERT(pobj != C_NULL); 00251 C_ASSERT(*r_pobj != C_NULL); 00252 00253 /* Raise a TypeError if pobj is not a sequence */ 00254 if ((OBJ_GET_TYPE(pobj) != OBJ_TYPE_STR) 00255 && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_TUP) 00256 && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_LST) 00257 && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_DIC)) 00258 { 00259 PM_RAISE(retval, PM_RET_EX_TYPE); 00260 return retval; 00261 } 00262 00263 /* Alloc a chunk for the sequence iterator obj */ 00264 retval = heap_getChunk(sizeof(PmSeqIter_t), &pchunk); 00265 PM_RETURN_IF_ERROR(retval); 00266 00267 /* Set the sequence iterator's fields */ 00268 psi = (pPmSeqIter_t)pchunk; 00269 OBJ_SET_TYPE(psi, OBJ_TYPE_SQI); 00270 psi->si_sequence = pobj; 00271 psi->si_index = 0; 00272 00273 *r_pobj = (pPmObj_t)psi; 00274 return retval; 00275 }
Generated on Tue Jul 12 2022 23:13:47 by
1.7.2