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.
src/vm/seq.c@1:979fdbf19fdf, 2010-07-26 (annotated)
- Committer:
- dadaista
- Date:
- Mon Jul 26 15:33:32 2010 +0000
- Revision:
- 1:979fdbf19fdf
- Parent:
- 0:14e5e829dffe
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| dadaista | 0:14e5e829dffe | 1 | /* |
| dadaista | 0:14e5e829dffe | 2 | # This file is Copyright 2006, 2007, 2009 Dean Hall. |
| dadaista | 0:14e5e829dffe | 3 | # |
| dadaista | 0:14e5e829dffe | 4 | # This file is part of the PyMite VM. |
| dadaista | 0:14e5e829dffe | 5 | # The PyMite VM is free software: you can redistribute it and/or modify |
| dadaista | 0:14e5e829dffe | 6 | # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2. |
| dadaista | 0:14e5e829dffe | 7 | # |
| dadaista | 0:14e5e829dffe | 8 | # The PyMite VM is distributed in the hope that it will be useful, |
| dadaista | 0:14e5e829dffe | 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| dadaista | 0:14e5e829dffe | 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| dadaista | 0:14e5e829dffe | 11 | # A copy of the GNU GENERAL PUBLIC LICENSE Version 2 |
| dadaista | 0:14e5e829dffe | 12 | # is seen in the file COPYING in this directory. |
| dadaista | 0:14e5e829dffe | 13 | */ |
| dadaista | 0:14e5e829dffe | 14 | |
| dadaista | 0:14e5e829dffe | 15 | |
| dadaista | 0:14e5e829dffe | 16 | #undef __FILE_ID__ |
| dadaista | 0:14e5e829dffe | 17 | #define __FILE_ID__ 0x14 |
| dadaista | 0:14e5e829dffe | 18 | |
| dadaista | 0:14e5e829dffe | 19 | |
| dadaista | 0:14e5e829dffe | 20 | /** |
| dadaista | 0:14e5e829dffe | 21 | * \file |
| dadaista | 0:14e5e829dffe | 22 | * \brief Sequence |
| dadaista | 0:14e5e829dffe | 23 | * |
| dadaista | 0:14e5e829dffe | 24 | * Functions that operate on sequences |
| dadaista | 0:14e5e829dffe | 25 | */ |
| dadaista | 0:14e5e829dffe | 26 | |
| dadaista | 0:14e5e829dffe | 27 | |
| dadaista | 0:14e5e829dffe | 28 | #include "pm.h" |
| dadaista | 0:14e5e829dffe | 29 | |
| dadaista | 0:14e5e829dffe | 30 | |
| dadaista | 0:14e5e829dffe | 31 | /* |
| dadaista | 0:14e5e829dffe | 32 | * Compares two sequence objects |
| dadaista | 0:14e5e829dffe | 33 | * Assumes both objects are of same type (guaranteed by obj_compare) |
| dadaista | 0:14e5e829dffe | 34 | */ |
| dadaista | 0:14e5e829dffe | 35 | int8_t |
| dadaista | 0:14e5e829dffe | 36 | seq_compare(pPmObj_t pobj1, pPmObj_t pobj2) |
| dadaista | 0:14e5e829dffe | 37 | { |
| dadaista | 0:14e5e829dffe | 38 | int16_t l1; |
| dadaista | 0:14e5e829dffe | 39 | int16_t l2; |
| dadaista | 0:14e5e829dffe | 40 | pPmObj_t pa; |
| dadaista | 0:14e5e829dffe | 41 | pPmObj_t pb; |
| dadaista | 0:14e5e829dffe | 42 | PmReturn_t retval; |
| dadaista | 0:14e5e829dffe | 43 | int8_t retcompare; |
| dadaista | 0:14e5e829dffe | 44 | |
| dadaista | 0:14e5e829dffe | 45 | /* Get the lengths of supported types or return differ */ |
| dadaista | 0:14e5e829dffe | 46 | if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_TUP) |
| dadaista | 0:14e5e829dffe | 47 | { |
| dadaista | 0:14e5e829dffe | 48 | l1 = ((pPmTuple_t)pobj1)->length; |
| dadaista | 0:14e5e829dffe | 49 | l2 = ((pPmTuple_t)pobj2)->length; |
| dadaista | 0:14e5e829dffe | 50 | } |
| dadaista | 0:14e5e829dffe | 51 | else if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_LST) |
| dadaista | 0:14e5e829dffe | 52 | { |
| dadaista | 0:14e5e829dffe | 53 | l1 = ((pPmList_t)pobj1)->length; |
| dadaista | 0:14e5e829dffe | 54 | l2 = ((pPmList_t)pobj2)->length; |
| dadaista | 0:14e5e829dffe | 55 | } |
| dadaista | 0:14e5e829dffe | 56 | |
| dadaista | 0:14e5e829dffe | 57 | #ifdef HAVE_BYTEARRAY |
| dadaista | 0:14e5e829dffe | 58 | else if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_BYA) |
| dadaista | 0:14e5e829dffe | 59 | { |
| dadaista | 0:14e5e829dffe | 60 | /* Return if the lengths differ */ |
| dadaista | 0:14e5e829dffe | 61 | l1 = ((pPmBytearray_t)pobj1)->length; |
| dadaista | 0:14e5e829dffe | 62 | l2 = ((pPmBytearray_t)pobj2)->length; |
| dadaista | 0:14e5e829dffe | 63 | if (l1 != l2) |
| dadaista | 0:14e5e829dffe | 64 | { |
| dadaista | 0:14e5e829dffe | 65 | return C_DIFFER; |
| dadaista | 0:14e5e829dffe | 66 | } |
| dadaista | 0:14e5e829dffe | 67 | |
| dadaista | 0:14e5e829dffe | 68 | return sli_strncmp((char const *)&(((pPmBytes_t)((pPmBytearray_t)pobj1)->val)->val), |
| dadaista | 0:14e5e829dffe | 69 | (char const *)&(((pPmBytes_t)((pPmBytearray_t)pobj2)->val)->val), |
| dadaista | 0:14e5e829dffe | 70 | l1) |
| dadaista | 0:14e5e829dffe | 71 | ? C_DIFFER : C_SAME; |
| dadaista | 0:14e5e829dffe | 72 | } |
| dadaista | 0:14e5e829dffe | 73 | #endif /* HAVE_BYTEARRAY */ |
| dadaista | 0:14e5e829dffe | 74 | |
| dadaista | 0:14e5e829dffe | 75 | else |
| dadaista | 0:14e5e829dffe | 76 | { |
| dadaista | 0:14e5e829dffe | 77 | return C_DIFFER; |
| dadaista | 0:14e5e829dffe | 78 | } |
| dadaista | 0:14e5e829dffe | 79 | |
| dadaista | 0:14e5e829dffe | 80 | /* Return if the lengths differ */ |
| dadaista | 0:14e5e829dffe | 81 | if (l1 != l2) |
| dadaista | 0:14e5e829dffe | 82 | { |
| dadaista | 0:14e5e829dffe | 83 | return C_DIFFER; |
| dadaista | 0:14e5e829dffe | 84 | } |
| dadaista | 0:14e5e829dffe | 85 | |
| dadaista | 0:14e5e829dffe | 86 | /* Compare all items in the sequences */ |
| dadaista | 0:14e5e829dffe | 87 | while (--l1 >= 0) |
| dadaista | 0:14e5e829dffe | 88 | { |
| dadaista | 0:14e5e829dffe | 89 | retval = seq_getSubscript(pobj1, l1, &pa); |
| dadaista | 0:14e5e829dffe | 90 | if (retval != PM_RET_OK) |
| dadaista | 0:14e5e829dffe | 91 | { |
| dadaista | 0:14e5e829dffe | 92 | return C_DIFFER; |
| dadaista | 0:14e5e829dffe | 93 | } |
| dadaista | 0:14e5e829dffe | 94 | retval = seq_getSubscript(pobj2, l1, &pb); |
| dadaista | 0:14e5e829dffe | 95 | if (retval != PM_RET_OK) |
| dadaista | 0:14e5e829dffe | 96 | { |
| dadaista | 0:14e5e829dffe | 97 | return C_DIFFER; |
| dadaista | 0:14e5e829dffe | 98 | } |
| dadaista | 0:14e5e829dffe | 99 | retcompare = obj_compare(pa, pb); |
| dadaista | 0:14e5e829dffe | 100 | if (retcompare != C_SAME) |
| dadaista | 0:14e5e829dffe | 101 | { |
| dadaista | 0:14e5e829dffe | 102 | return retcompare; |
| dadaista | 0:14e5e829dffe | 103 | } |
| dadaista | 0:14e5e829dffe | 104 | } |
| dadaista | 0:14e5e829dffe | 105 | |
| dadaista | 0:14e5e829dffe | 106 | return C_SAME; |
| dadaista | 0:14e5e829dffe | 107 | } |
| dadaista | 0:14e5e829dffe | 108 | |
| dadaista | 0:14e5e829dffe | 109 | |
| dadaista | 0:14e5e829dffe | 110 | /* Returns the length of the sequence */ |
| dadaista | 0:14e5e829dffe | 111 | PmReturn_t |
| dadaista | 0:14e5e829dffe | 112 | seq_getLength(pPmObj_t pobj, int16_t *r_index) |
| dadaista | 0:14e5e829dffe | 113 | { |
| dadaista | 0:14e5e829dffe | 114 | PmReturn_t retval = PM_RET_OK; |
| dadaista | 0:14e5e829dffe | 115 | |
| dadaista | 0:14e5e829dffe | 116 | switch (OBJ_GET_TYPE(pobj)) |
| dadaista | 0:14e5e829dffe | 117 | { |
| dadaista | 0:14e5e829dffe | 118 | case OBJ_TYPE_STR: |
| dadaista | 0:14e5e829dffe | 119 | *r_index = ((pPmString_t)pobj)->length; |
| dadaista | 0:14e5e829dffe | 120 | break; |
| dadaista | 0:14e5e829dffe | 121 | |
| dadaista | 0:14e5e829dffe | 122 | case OBJ_TYPE_TUP: |
| dadaista | 0:14e5e829dffe | 123 | *r_index = ((pPmTuple_t)pobj)->length; |
| dadaista | 0:14e5e829dffe | 124 | break; |
| dadaista | 0:14e5e829dffe | 125 | |
| dadaista | 0:14e5e829dffe | 126 | case OBJ_TYPE_LST: |
| dadaista | 0:14e5e829dffe | 127 | *r_index = ((pPmList_t)pobj)->length; |
| dadaista | 0:14e5e829dffe | 128 | break; |
| dadaista | 0:14e5e829dffe | 129 | |
| dadaista | 0:14e5e829dffe | 130 | #ifdef HAVE_BYTEARRAY |
| dadaista | 0:14e5e829dffe | 131 | case OBJ_TYPE_BYA: |
| dadaista | 0:14e5e829dffe | 132 | *r_index = ((pPmBytearray_t)pobj)->length; |
| dadaista | 0:14e5e829dffe | 133 | break; |
| dadaista | 0:14e5e829dffe | 134 | #endif /* HAVE_BYTEARRAY */ |
| dadaista | 0:14e5e829dffe | 135 | |
| dadaista | 0:14e5e829dffe | 136 | default: |
| dadaista | 0:14e5e829dffe | 137 | /* Raise TypeError, non-sequence object */ |
| dadaista | 0:14e5e829dffe | 138 | PM_RAISE(retval, PM_RET_EX_TYPE); |
| dadaista | 0:14e5e829dffe | 139 | break; |
| dadaista | 0:14e5e829dffe | 140 | } |
| dadaista | 0:14e5e829dffe | 141 | |
| dadaista | 0:14e5e829dffe | 142 | return retval; |
| dadaista | 0:14e5e829dffe | 143 | } |
| dadaista | 0:14e5e829dffe | 144 | |
| dadaista | 0:14e5e829dffe | 145 | |
| dadaista | 0:14e5e829dffe | 146 | /* Returns the object sequence[index] */ |
| dadaista | 0:14e5e829dffe | 147 | PmReturn_t |
| dadaista | 0:14e5e829dffe | 148 | seq_getSubscript(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj) |
| dadaista | 0:14e5e829dffe | 149 | { |
| dadaista | 0:14e5e829dffe | 150 | PmReturn_t retval; |
| dadaista | 0:14e5e829dffe | 151 | uint8_t c; |
| dadaista | 0:14e5e829dffe | 152 | |
| dadaista | 0:14e5e829dffe | 153 | switch (OBJ_GET_TYPE(pobj)) |
| dadaista | 0:14e5e829dffe | 154 | { |
| dadaista | 0:14e5e829dffe | 155 | case OBJ_TYPE_STR: |
| dadaista | 0:14e5e829dffe | 156 | /* Adjust for negative index */ |
| dadaista | 0:14e5e829dffe | 157 | if (index < 0) |
| dadaista | 0:14e5e829dffe | 158 | { |
| dadaista | 0:14e5e829dffe | 159 | index += ((pPmString_t)pobj)->length; |
| dadaista | 0:14e5e829dffe | 160 | } |
| dadaista | 0:14e5e829dffe | 161 | |
| dadaista | 0:14e5e829dffe | 162 | /* Raise IndexError if index is out of bounds */ |
| dadaista | 0:14e5e829dffe | 163 | if ((index < 0) || (index > ((pPmString_t)pobj)->length)) |
| dadaista | 0:14e5e829dffe | 164 | { |
| dadaista | 0:14e5e829dffe | 165 | PM_RAISE(retval, PM_RET_EX_INDX); |
| dadaista | 0:14e5e829dffe | 166 | break; |
| dadaista | 0:14e5e829dffe | 167 | } |
| dadaista | 0:14e5e829dffe | 168 | |
| dadaista | 0:14e5e829dffe | 169 | /* Get the character from the string */ |
| dadaista | 0:14e5e829dffe | 170 | c = ((pPmString_t)pobj)->val[index]; |
| dadaista | 0:14e5e829dffe | 171 | |
| dadaista | 0:14e5e829dffe | 172 | /* Create a new string from the character */ |
| dadaista | 0:14e5e829dffe | 173 | retval = string_newFromChar(c, r_pobj); |
| dadaista | 0:14e5e829dffe | 174 | break; |
| dadaista | 0:14e5e829dffe | 175 | |
| dadaista | 0:14e5e829dffe | 176 | case OBJ_TYPE_TUP: |
| dadaista | 0:14e5e829dffe | 177 | /* Get the tuple item */ |
| dadaista | 0:14e5e829dffe | 178 | retval = tuple_getItem(pobj, index, r_pobj); |
| dadaista | 0:14e5e829dffe | 179 | break; |
| dadaista | 0:14e5e829dffe | 180 | |
| dadaista | 0:14e5e829dffe | 181 | case OBJ_TYPE_LST: |
| dadaista | 0:14e5e829dffe | 182 | /* Get the list item */ |
| dadaista | 0:14e5e829dffe | 183 | retval = list_getItem(pobj, index, r_pobj); |
| dadaista | 0:14e5e829dffe | 184 | break; |
| dadaista | 0:14e5e829dffe | 185 | |
| dadaista | 0:14e5e829dffe | 186 | #ifdef HAVE_BYTEARRAY |
| dadaista | 0:14e5e829dffe | 187 | case OBJ_TYPE_BYA: |
| dadaista | 0:14e5e829dffe | 188 | retval = bytearray_getItem(pobj, index, r_pobj); |
| dadaista | 0:14e5e829dffe | 189 | break; |
| dadaista | 0:14e5e829dffe | 190 | #endif /* HAVE_BYTEARRAY */ |
| dadaista | 0:14e5e829dffe | 191 | |
| dadaista | 0:14e5e829dffe | 192 | default: |
| dadaista | 0:14e5e829dffe | 193 | /* Raise TypeError, unsubscriptable object */ |
| dadaista | 0:14e5e829dffe | 194 | PM_RAISE(retval, PM_RET_EX_TYPE); |
| dadaista | 0:14e5e829dffe | 195 | break; |
| dadaista | 0:14e5e829dffe | 196 | } |
| dadaista | 0:14e5e829dffe | 197 | |
| dadaista | 0:14e5e829dffe | 198 | return retval; |
| dadaista | 0:14e5e829dffe | 199 | } |
| dadaista | 0:14e5e829dffe | 200 | |
| dadaista | 0:14e5e829dffe | 201 | |
| dadaista | 0:14e5e829dffe | 202 | PmReturn_t |
| dadaista | 0:14e5e829dffe | 203 | seqiter_getNext(pPmObj_t pobj, pPmObj_t *r_pitem) |
| dadaista | 0:14e5e829dffe | 204 | { |
| dadaista | 0:14e5e829dffe | 205 | PmReturn_t retval; |
| dadaista | 0:14e5e829dffe | 206 | int16_t length; |
| dadaista | 0:14e5e829dffe | 207 | |
| dadaista | 0:14e5e829dffe | 208 | C_ASSERT(pobj != C_NULL); |
| dadaista | 0:14e5e829dffe | 209 | C_ASSERT(*r_pitem != C_NULL); |
| dadaista | 0:14e5e829dffe | 210 | C_ASSERT(OBJ_GET_TYPE(pobj) == OBJ_TYPE_SQI); |
| dadaista | 0:14e5e829dffe | 211 | |
| dadaista | 0:14e5e829dffe | 212 | /* |
| dadaista | 0:14e5e829dffe | 213 | * Raise TypeError if sequence iterator's object is not a sequence |
| dadaista | 0:14e5e829dffe | 214 | * otherwise, the get sequence's length |
| dadaista | 0:14e5e829dffe | 215 | */ |
| dadaista | 0:14e5e829dffe | 216 | retval = seq_getLength(((pPmSeqIter_t)pobj)->si_sequence, &length); |
| dadaista | 0:14e5e829dffe | 217 | PM_RETURN_IF_ERROR(retval); |
| dadaista | 0:14e5e829dffe | 218 | |
| dadaista | 0:14e5e829dffe | 219 | /* Raise StopIteration if at the end of the sequence */ |
| dadaista | 0:14e5e829dffe | 220 | if (((pPmSeqIter_t)pobj)->si_index == length) |
| dadaista | 0:14e5e829dffe | 221 | { |
| dadaista | 0:14e5e829dffe | 222 | /* Make null the pointer to the sequence */ |
| dadaista | 0:14e5e829dffe | 223 | ((pPmSeqIter_t)pobj)->si_sequence = C_NULL; |
| dadaista | 0:14e5e829dffe | 224 | PM_RAISE(retval, PM_RET_EX_STOP); |
| dadaista | 0:14e5e829dffe | 225 | return retval; |
| dadaista | 0:14e5e829dffe | 226 | } |
| dadaista | 0:14e5e829dffe | 227 | |
| dadaista | 0:14e5e829dffe | 228 | /* Get the item at the current index */ |
| dadaista | 0:14e5e829dffe | 229 | retval = seq_getSubscript(((pPmSeqIter_t)pobj)->si_sequence, |
| dadaista | 0:14e5e829dffe | 230 | ((pPmSeqIter_t)pobj)->si_index, r_pitem); |
| dadaista | 0:14e5e829dffe | 231 | |
| dadaista | 0:14e5e829dffe | 232 | /* Increment the index */ |
| dadaista | 0:14e5e829dffe | 233 | ((pPmSeqIter_t)pobj)->si_index++; |
| dadaista | 0:14e5e829dffe | 234 | |
| dadaista | 0:14e5e829dffe | 235 | return retval; |
| dadaista | 0:14e5e829dffe | 236 | } |
| dadaista | 0:14e5e829dffe | 237 | |
| dadaista | 0:14e5e829dffe | 238 | |
| dadaista | 0:14e5e829dffe | 239 | PmReturn_t |
| dadaista | 0:14e5e829dffe | 240 | seqiter_new(pPmObj_t pobj, pPmObj_t *r_pobj) |
| dadaista | 0:14e5e829dffe | 241 | { |
| dadaista | 0:14e5e829dffe | 242 | PmReturn_t retval; |
| dadaista | 0:14e5e829dffe | 243 | uint8_t *pchunk; |
| dadaista | 0:14e5e829dffe | 244 | pPmSeqIter_t psi; |
| dadaista | 0:14e5e829dffe | 245 | |
| dadaista | 0:14e5e829dffe | 246 | C_ASSERT(pobj != C_NULL); |
| dadaista | 0:14e5e829dffe | 247 | C_ASSERT(*r_pobj != C_NULL); |
| dadaista | 0:14e5e829dffe | 248 | |
| dadaista | 0:14e5e829dffe | 249 | /* Raise a TypeError if pobj is not a sequence */ |
| dadaista | 0:14e5e829dffe | 250 | if ((OBJ_GET_TYPE(pobj) != OBJ_TYPE_STR) |
| dadaista | 0:14e5e829dffe | 251 | && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_TUP) |
| dadaista | 0:14e5e829dffe | 252 | && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_LST)) |
| dadaista | 0:14e5e829dffe | 253 | { |
| dadaista | 0:14e5e829dffe | 254 | PM_RAISE(retval, PM_RET_EX_TYPE); |
| dadaista | 0:14e5e829dffe | 255 | return retval; |
| dadaista | 0:14e5e829dffe | 256 | } |
| dadaista | 0:14e5e829dffe | 257 | |
| dadaista | 0:14e5e829dffe | 258 | /* Alloc a chunk for the sequence iterator obj */ |
| dadaista | 0:14e5e829dffe | 259 | retval = heap_getChunk(sizeof(PmSeqIter_t), &pchunk); |
| dadaista | 0:14e5e829dffe | 260 | PM_RETURN_IF_ERROR(retval); |
| dadaista | 0:14e5e829dffe | 261 | |
| dadaista | 0:14e5e829dffe | 262 | /* Set the sequence iterator's fields */ |
| dadaista | 0:14e5e829dffe | 263 | psi = (pPmSeqIter_t)pchunk; |
| dadaista | 0:14e5e829dffe | 264 | OBJ_SET_TYPE(psi, OBJ_TYPE_SQI); |
| dadaista | 0:14e5e829dffe | 265 | psi->si_sequence = pobj; |
| dadaista | 0:14e5e829dffe | 266 | psi->si_index = 0; |
| dadaista | 0:14e5e829dffe | 267 | |
| dadaista | 0:14e5e829dffe | 268 | *r_pobj = (pPmObj_t)psi; |
| dadaista | 0:14e5e829dffe | 269 | return retval; |
| dadaista | 0:14e5e829dffe | 270 | } |