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