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.
Diff: src/vm/seq.c
- Revision:
- 0:14e5e829dffe
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vm/seq.c Wed Jul 21 12:50:41 2010 +0000
@@ -0,0 +1,270 @@
+/*
+# This file is Copyright 2006, 2007, 2009 Dean Hall.
+#
+# This file is part of the PyMite VM.
+# The PyMite VM is free software: you can redistribute it and/or modify
+# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
+#
+# The PyMite VM is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# A copy of the GNU GENERAL PUBLIC LICENSE Version 2
+# is seen in the file COPYING in this directory.
+*/
+
+
+#undef __FILE_ID__
+#define __FILE_ID__ 0x14
+
+
+/**
+ * \file
+ * \brief Sequence
+ *
+ * Functions that operate on sequences
+ */
+
+
+#include "pm.h"
+
+
+/*
+ * Compares two sequence objects
+ * Assumes both objects are of same type (guaranteed by obj_compare)
+ */
+int8_t
+seq_compare(pPmObj_t pobj1, pPmObj_t pobj2)
+{
+ int16_t l1;
+ int16_t l2;
+ pPmObj_t pa;
+ pPmObj_t pb;
+ PmReturn_t retval;
+ int8_t retcompare;
+
+ /* Get the lengths of supported types or return differ */
+ if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_TUP)
+ {
+ l1 = ((pPmTuple_t)pobj1)->length;
+ l2 = ((pPmTuple_t)pobj2)->length;
+ }
+ else if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_LST)
+ {
+ l1 = ((pPmList_t)pobj1)->length;
+ l2 = ((pPmList_t)pobj2)->length;
+ }
+
+#ifdef HAVE_BYTEARRAY
+ else if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_BYA)
+ {
+ /* Return if the lengths differ */
+ l1 = ((pPmBytearray_t)pobj1)->length;
+ l2 = ((pPmBytearray_t)pobj2)->length;
+ if (l1 != l2)
+ {
+ return C_DIFFER;
+ }
+
+ return sli_strncmp((char const *)&(((pPmBytes_t)((pPmBytearray_t)pobj1)->val)->val),
+ (char const *)&(((pPmBytes_t)((pPmBytearray_t)pobj2)->val)->val),
+ l1)
+ ? C_DIFFER : C_SAME;
+ }
+#endif /* HAVE_BYTEARRAY */
+
+ else
+ {
+ return C_DIFFER;
+ }
+
+ /* Return if the lengths differ */
+ if (l1 != l2)
+ {
+ return C_DIFFER;
+ }
+
+ /* Compare all items in the sequences */
+ while (--l1 >= 0)
+ {
+ retval = seq_getSubscript(pobj1, l1, &pa);
+ if (retval != PM_RET_OK)
+ {
+ return C_DIFFER;
+ }
+ retval = seq_getSubscript(pobj2, l1, &pb);
+ if (retval != PM_RET_OK)
+ {
+ return C_DIFFER;
+ }
+ retcompare = obj_compare(pa, pb);
+ if (retcompare != C_SAME)
+ {
+ return retcompare;
+ }
+ }
+
+ return C_SAME;
+}
+
+
+/* Returns the length of the sequence */
+PmReturn_t
+seq_getLength(pPmObj_t pobj, int16_t *r_index)
+{
+ PmReturn_t retval = PM_RET_OK;
+
+ switch (OBJ_GET_TYPE(pobj))
+ {
+ case OBJ_TYPE_STR:
+ *r_index = ((pPmString_t)pobj)->length;
+ break;
+
+ case OBJ_TYPE_TUP:
+ *r_index = ((pPmTuple_t)pobj)->length;
+ break;
+
+ case OBJ_TYPE_LST:
+ *r_index = ((pPmList_t)pobj)->length;
+ break;
+
+#ifdef HAVE_BYTEARRAY
+ case OBJ_TYPE_BYA:
+ *r_index = ((pPmBytearray_t)pobj)->length;
+ break;
+#endif /* HAVE_BYTEARRAY */
+
+ default:
+ /* Raise TypeError, non-sequence object */
+ PM_RAISE(retval, PM_RET_EX_TYPE);
+ break;
+ }
+
+ return retval;
+}
+
+
+/* Returns the object sequence[index] */
+PmReturn_t
+seq_getSubscript(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj)
+{
+ PmReturn_t retval;
+ uint8_t c;
+
+ switch (OBJ_GET_TYPE(pobj))
+ {
+ case OBJ_TYPE_STR:
+ /* Adjust for negative index */
+ if (index < 0)
+ {
+ index += ((pPmString_t)pobj)->length;
+ }
+
+ /* Raise IndexError if index is out of bounds */
+ if ((index < 0) || (index > ((pPmString_t)pobj)->length))
+ {
+ PM_RAISE(retval, PM_RET_EX_INDX);
+ break;
+ }
+
+ /* Get the character from the string */
+ c = ((pPmString_t)pobj)->val[index];
+
+ /* Create a new string from the character */
+ retval = string_newFromChar(c, r_pobj);
+ break;
+
+ case OBJ_TYPE_TUP:
+ /* Get the tuple item */
+ retval = tuple_getItem(pobj, index, r_pobj);
+ break;
+
+ case OBJ_TYPE_LST:
+ /* Get the list item */
+ retval = list_getItem(pobj, index, r_pobj);
+ break;
+
+#ifdef HAVE_BYTEARRAY
+ case OBJ_TYPE_BYA:
+ retval = bytearray_getItem(pobj, index, r_pobj);
+ break;
+#endif /* HAVE_BYTEARRAY */
+
+ default:
+ /* Raise TypeError, unsubscriptable object */
+ PM_RAISE(retval, PM_RET_EX_TYPE);
+ break;
+ }
+
+ return retval;
+}
+
+
+PmReturn_t
+seqiter_getNext(pPmObj_t pobj, pPmObj_t *r_pitem)
+{
+ PmReturn_t retval;
+ int16_t length;
+
+ C_ASSERT(pobj != C_NULL);
+ C_ASSERT(*r_pitem != C_NULL);
+ C_ASSERT(OBJ_GET_TYPE(pobj) == OBJ_TYPE_SQI);
+
+ /*
+ * Raise TypeError if sequence iterator's object is not a sequence
+ * otherwise, the get sequence's length
+ */
+ retval = seq_getLength(((pPmSeqIter_t)pobj)->si_sequence, &length);
+ PM_RETURN_IF_ERROR(retval);
+
+ /* Raise StopIteration if at the end of the sequence */
+ if (((pPmSeqIter_t)pobj)->si_index == length)
+ {
+ /* Make null the pointer to the sequence */
+ ((pPmSeqIter_t)pobj)->si_sequence = C_NULL;
+ PM_RAISE(retval, PM_RET_EX_STOP);
+ return retval;
+ }
+
+ /* Get the item at the current index */
+ retval = seq_getSubscript(((pPmSeqIter_t)pobj)->si_sequence,
+ ((pPmSeqIter_t)pobj)->si_index, r_pitem);
+
+ /* Increment the index */
+ ((pPmSeqIter_t)pobj)->si_index++;
+
+ return retval;
+}
+
+
+PmReturn_t
+seqiter_new(pPmObj_t pobj, pPmObj_t *r_pobj)
+{
+ PmReturn_t retval;
+ uint8_t *pchunk;
+ pPmSeqIter_t psi;
+
+ C_ASSERT(pobj != C_NULL);
+ C_ASSERT(*r_pobj != C_NULL);
+
+ /* Raise a TypeError if pobj is not a sequence */
+ if ((OBJ_GET_TYPE(pobj) != OBJ_TYPE_STR)
+ && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_TUP)
+ && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_LST))
+ {
+ PM_RAISE(retval, PM_RET_EX_TYPE);
+ return retval;
+ }
+
+ /* Alloc a chunk for the sequence iterator obj */
+ retval = heap_getChunk(sizeof(PmSeqIter_t), &pchunk);
+ PM_RETURN_IF_ERROR(retval);
+
+ /* Set the sequence iterator's fields */
+ psi = (pPmSeqIter_t)pchunk;
+ OBJ_SET_TYPE(psi, OBJ_TYPE_SQI);
+ psi->si_sequence = pobj;
+ psi->si_index = 0;
+
+ *r_pobj = (pPmObj_t)psi;
+ return retval;
+}