python-on-a-chip online compiler

Dependencies:   mbed TSI

/media/uploads/va009039/p14p-f446re.png

more info: python-on-a-chip

Revision:
0:65f1469d6bfb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm/list.c	Sat Mar 02 11:54:20 2013 +0000
@@ -0,0 +1,417 @@
+/*
+# This file is Copyright 2002 Dean Hall.
+# This file is part of the PyMite VM.
+# This file is licensed under the MIT License.
+# See the LICENSE file for details.
+*/
+
+
+#undef __FILE_ID__
+#define __FILE_ID__ 0x0B
+
+
+/**
+ * \file
+ * \brief List Object Type
+ *
+ * List object type operations.
+ */
+
+
+#include "pm.h"
+
+
+PmReturn_t
+list_append(pPmObj_t plist, pPmObj_t pobj)
+{
+    PmReturn_t retval;
+    uint8_t objid;
+
+    C_ASSERT(plist != C_NULL);
+    C_ASSERT(pobj != C_NULL);
+
+    /* If plist is not a list, raise a TypeError exception */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Create new seglist if needed */
+    if (((pPmList_t)plist)->length == 0)
+    {
+        retval = seglist_new(&((pPmList_t)plist)->val);
+        PM_RETURN_IF_ERROR(retval);
+    }
+
+    /* Append object to list */
+    heap_gcPushTempRoot((pPmObj_t)((pPmList_t)plist)->val, &objid);
+    retval = seglist_appendItem(((pPmList_t)plist)->val, pobj);
+    heap_gcPopTempRoot(objid);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Increment list length */
+    ((pPmList_t)plist)->length++;
+
+    return retval;
+}
+
+
+PmReturn_t
+list_getItem(pPmObj_t plist, int16_t index, pPmObj_t *r_pobj)
+{
+    PmReturn_t retval;
+
+    /* If it's not a list, raise TypeError */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Adjust the index */
+    if (index < 0)
+    {
+        index += ((pPmList_t)plist)->length;
+    }
+
+    /* Check the bounds of the index */
+    if ((index < 0) || (index >= ((pPmList_t)plist)->length))
+    {
+        PM_RAISE(retval, PM_RET_EX_INDX);
+        return retval;
+    }
+
+    /* Get item from seglist */
+    retval = seglist_getItem(((pPmList_t)plist)->val, index, r_pobj);
+    return retval;
+}
+
+
+PmReturn_t
+list_insert(pPmObj_t plist, int16_t index, pPmObj_t pobj)
+{
+    PmReturn_t retval;
+    int16_t len;
+    uint8_t objid;
+
+    C_ASSERT(plist != C_NULL);
+    C_ASSERT(pobj != C_NULL);
+
+    /* Raise a TypeError if plist is not a List */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        retval = PM_RET_EX_TYPE;
+        PM_RETURN_IF_ERROR(retval);
+    }
+
+    /* Adjust an out-of-bounds index value */
+    len = ((pPmList_t)plist)->length;
+    if (index < 0)
+    {
+        index += len;
+    }
+    if (index < 0)
+    {
+        index = 0;
+    }
+    if (index > len)
+    {
+        index = len;
+    }
+
+    /* Create new seglist if needed */
+    if (((pPmList_t)plist)->length == 0)
+    {
+        retval = seglist_new(&((pPmList_t)plist)->val);
+        PM_RETURN_IF_ERROR(retval);
+    }
+
+    /* Insert the item in the container */
+    heap_gcPushTempRoot((pPmObj_t)((pPmList_t)plist)->val, &objid);
+    retval = seglist_insertItem(((pPmList_t)plist)->val, pobj, index);
+    heap_gcPopTempRoot(objid);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Increment list length */
+    ((pPmList_t)plist)->length++;
+    return retval;
+}
+
+
+PmReturn_t
+list_new(pPmObj_t *r_pobj)
+{
+    PmReturn_t retval = PM_RET_OK;
+    pPmList_t plist = C_NULL;
+
+    /* Allocate a list */
+    retval = heap_getChunk(sizeof(PmList_t), (uint8_t **)r_pobj);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Set list type, empty the contents */
+    plist = (pPmList_t)*r_pobj;
+    OBJ_SET_TYPE(plist, OBJ_TYPE_LST);
+    plist->length = 0;
+    plist->val = C_NULL;
+
+    return retval;
+}
+
+
+PmReturn_t
+list_copy(pPmObj_t pobj, pPmObj_t *r_pobj)
+{
+    return list_replicate(pobj, 1, r_pobj);
+}
+
+
+PmReturn_t
+list_replicate(pPmObj_t psrclist, int16_t n, pPmObj_t *r_pnewlist)
+{
+    PmReturn_t retval = PM_RET_OK;
+    int16_t i = 0;
+    int16_t j = 0;
+    int16_t length = 0;
+    pPmObj_t pitem = C_NULL;
+    uint8_t objid;
+
+    C_ASSERT(psrclist != C_NULL);
+    C_ASSERT(r_pnewlist != C_NULL);
+
+    /* If first arg is not a list, raise TypeError */
+    if (OBJ_GET_TYPE(psrclist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+    length = ((pPmList_t)psrclist)->length;
+
+    /* Allocate new list */
+    retval = list_new(r_pnewlist);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Copy srclist the designated number of times */
+    for (i = n; i > 0; i--)
+    {
+        /* Iterate over the length of srclist */
+        for (j = 0; j < length; j++)
+        {
+            retval = list_getItem(psrclist, j, &pitem);
+            PM_RETURN_IF_ERROR(retval);
+            heap_gcPushTempRoot(*r_pnewlist, &objid);
+            retval = list_append(*r_pnewlist, pitem);
+            heap_gcPopTempRoot(objid);
+            PM_RETURN_IF_ERROR(retval);
+        }
+    }
+    return retval;
+}
+
+
+PmReturn_t
+list_setItem(pPmObj_t plist, int16_t index, pPmObj_t pobj)
+{
+    PmReturn_t retval;
+
+    /* If it's not a list, raise TypeError */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Adjust the index */
+    if (index < 0)
+    {
+        index += ((pPmList_t)plist)->length;
+    }
+
+    /* Check the bounds of the index */
+    if ((index < 0) || (index >= ((pPmList_t)plist)->length))
+    {
+        PM_RAISE(retval, PM_RET_EX_INDX);
+        return retval;
+    }
+
+    /* Set the item */
+    retval = seglist_setItem(((pPmList_t)plist)->val, pobj, index);
+    return retval;
+}
+
+
+PmReturn_t
+list_remove(pPmObj_t plist, pPmObj_t item)
+{
+    PmReturn_t retval = PM_RET_OK;
+    uint16_t index;
+
+    /* If it's not a list, raise TypeError */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Locate the item to remove */
+    retval = list_index(plist, item, &index);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Remove the item and decrement the list length */
+    retval = seglist_removeItem(((pPmList_t)plist)->val, index);
+    ((pPmList_t)plist)->length--;
+
+    /* Unlink seglist if there are no contents */
+    if (((pPmList_t)plist)->length == 0)
+    {
+        ((pPmList_t)plist)->val = C_NULL;
+    }
+
+    return retval;
+}
+
+
+PmReturn_t
+list_index(pPmObj_t plist, pPmObj_t pitem, uint16_t *r_index)
+{
+    PmReturn_t retval = PM_RET_OK;
+    pSeglist_t pseglist;
+    pPmObj_t pobj;
+    uint16_t index;
+
+    /* If it's not a list, raise TypeError */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Raise a ValueError if the list is empty */
+    if (((pPmList_t)plist)->length == 0)
+    {
+        PM_RAISE(retval, PM_RET_EX_VAL);
+        return retval;
+    }
+
+    pseglist = ((pPmList_t)plist)->val;
+
+    /* Iterate over the list's contents */
+    for (index = 0; index < pseglist->sl_length; index++)
+    {
+        retval = seglist_getItem(pseglist, index, &pobj);
+        PM_RETURN_IF_ERROR(retval);
+
+        /* If the list item matches the given item, return the index */
+        if (obj_compare(pobj, pitem) == C_SAME)
+        {
+            *r_index = index;
+            return PM_RET_OK;
+        }
+    }
+
+    return PM_RET_EX_VAL;
+}
+
+
+PmReturn_t
+list_delItem(pPmObj_t plist, int16_t index)
+{
+    PmReturn_t retval = PM_RET_OK;
+
+    /* If it's not a list, raise TypeError */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Adjust the index */
+    if (index < 0)
+    {
+        index += ((pPmList_t)plist)->length;
+    }
+
+    /* Check the bounds of the index */
+    if ((index < 0) || (index >= ((pPmList_t)plist)->length))
+    {
+        PM_RAISE(retval, PM_RET_EX_INDX);
+        return retval;
+    }
+
+    /* Remove the item and decrement the list length */
+    retval = seglist_removeItem(((pPmList_t)plist)->val, index);
+    ((pPmList_t)plist)->length--;
+
+    /* Unlink seglist if there are no contents */
+    if (((pPmList_t)plist)->length == 0)
+    {
+        ((pPmList_t)plist)->val = C_NULL;
+    }
+
+    return retval;
+}
+
+
+#ifdef HAVE_PRINT
+PmReturn_t
+list_print(pPmObj_t plist)
+{
+    PmReturn_t retval = PM_RET_OK;
+    int16_t index;
+    pSeglist_t vals;
+    pPmObj_t pobj1;
+
+    C_ASSERT(plist != C_NULL);
+
+    /* If it's not a list, raise TypeError */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    plat_putByte('[');
+
+    vals = ((pPmList_t)plist)->val;
+
+    /* Iterate over the list's contents */
+    for (index = 0; index < ((pPmList_t)plist)->length; index++)
+    {
+        if (index != 0)
+        {
+            plat_putByte(',');
+            plat_putByte(' ');
+        }
+
+        /* Print each item */
+        retval = seglist_getItem(vals, index, &pobj1);
+        PM_RETURN_IF_ERROR(retval);
+        retval = obj_print(pobj1, C_FALSE, C_TRUE);
+        PM_RETURN_IF_ERROR(retval);
+    }
+
+    return plat_putByte(']');
+}
+#endif /* HAVE_PRINT */
+
+
+PmReturn_t
+list_clear(pPmObj_t plist)
+{
+    PmReturn_t retval = PM_RET_OK;
+
+    C_ASSERT(plist != C_NULL);
+
+    /* Raise TypeError if arg is not a dict */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Clear length and unlink seglist */
+    ((pPmList_t)plist)->length = 0;
+    ((pPmList_t)plist)->val = C_NULL;
+
+    return retval;
+}