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/bytearray.c	Sat Mar 02 11:54:20 2013 +0000
@@ -0,0 +1,267 @@
+/*
+# This file is Copyright 2010 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__ 0x19
+
+
+/**
+ * \file
+ * \brief VM Bytearray Type
+ *
+ * VM Bytearray object type operations.
+ */
+
+#include "pm.h"
+#ifdef HAVE_BYTEARRAY
+
+
+#define ROUND_UP_TO_MUL_OF_FOUR(n) n = (((n) + 3) & ~3)
+
+
+/* Returns a container that can hold at least n bytes */
+static
+PmReturn_t
+bytes_new(int16_t n, pPmObj_t *r_pobj)
+{
+    PmReturn_t retval = PM_RET_OK;
+    pPmBytes_t pb = C_NULL;
+
+    ROUND_UP_TO_MUL_OF_FOUR(n);
+
+    /* Allocate a container */
+    retval = heap_getChunk(sizeof(PmBytes_t) + n, (uint8_t **)&pb);
+    PM_RETURN_IF_ERROR(retval);
+    OBJ_SET_TYPE(pb, OBJ_TYPE_BYS);
+    pb->length = n;
+
+    *r_pobj = (pPmObj_t)pb;
+    return retval;
+}
+
+
+/* Returns the int or one-char string as a byte */
+static
+PmReturn_t
+bytes_getByteFromObj(pPmObj_t pobj, uint8_t *b)
+{
+    PmReturn_t retval = PM_RET_OK;
+
+    if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_INT)
+    {
+        if ((((pPmInt_t)pobj)->val > 255) || (((pPmInt_t)pobj)->val < 0))
+        {
+            PM_RAISE(retval, PM_RET_EX_VAL);
+            return retval;
+        }
+
+        *b = (uint8_t)((pPmInt_t)pobj)->val;
+    }
+
+    else if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_STR)
+    {
+        if (((pPmString_t)pobj)->length != 1)
+        {
+            PM_RAISE(retval, PM_RET_EX_VAL);
+            return retval;
+        }
+        *b = ((pPmString_t)pobj)->val[0];
+    }
+
+    else
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+    }
+    return retval;
+}
+
+
+PmReturn_t
+bytearray_new(pPmObj_t pobj, pPmObj_t *r_pobj)
+{
+    PmReturn_t retval = PM_RET_OK;
+    pPmBytearray_t pba = C_NULL;
+    pPmBytes_t pb = C_NULL;
+    pPmObj_t pitem;
+    int32_t i;
+    int16_t n;
+    uint8_t b;
+    uint8_t objid;
+
+    /* If object is an instance, get the thing it is containing */
+    if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLI)
+    {
+        retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs,
+                              PM_NONE,
+                              (pPmObj_t *)&pba);
+        PM_RETURN_IF_ERROR(retval);
+        pobj = (pPmObj_t)pba;
+    }
+
+    /* Get the requested length of the new bytearray */
+    switch (OBJ_GET_TYPE(pobj))
+    {
+        case OBJ_TYPE_INT:
+            i = ((pPmInt_t)pobj)->val;
+            if ((i < 0) || (i > 65535))
+            {
+                PM_RAISE(retval, PM_RET_EX_VAL);
+                return retval;
+            }
+            n = i;
+            break;
+
+        case OBJ_TYPE_STR:
+            n = ((pPmString_t)pobj)->length;
+            break;
+
+        case OBJ_TYPE_LST:
+            n = ((pPmList_t)pobj)->length;
+            break;
+
+        case OBJ_TYPE_TUP:
+            n = ((pPmTuple_t)pobj)->length;
+            break;
+
+        case OBJ_TYPE_BYA:
+            n = ((pPmBytearray_t)pobj)->length;
+            break;
+
+        default:
+            PM_RAISE(retval, PM_RET_EX_TYPE);
+            return retval;
+    }
+
+    /* Allocate a bytearray */
+    retval = heap_getChunk(sizeof(PmBytearray_t), (uint8_t **)&pba);
+    PM_RETURN_IF_ERROR(retval);
+    OBJ_SET_TYPE(pba, OBJ_TYPE_BYA);
+    pba->length = n;
+    pba->val = C_NULL;
+
+    /* Allocate the bytes container */
+    heap_gcPushTempRoot((pPmObj_t)pba, &objid);
+    retval = bytes_new(n, (pPmObj_t *)&pb);
+    heap_gcPopTempRoot(objid);
+    PM_RETURN_IF_ERROR(retval);
+    pba->val = pb;
+
+    /* Fill the bytes */
+    switch (OBJ_GET_TYPE(pobj))
+    {
+        case OBJ_TYPE_INT:
+            sli_memset((unsigned char *)&(pb->val), '\0', n);
+            break;
+
+        case OBJ_TYPE_BYA:
+            pitem = (pPmObj_t)((pPmBytearray_t)pobj)->val;
+            sli_memcpy(&(pb->val[0]), &(((pPmBytes_t)pitem)->val[0]), n);
+            break;
+
+        case OBJ_TYPE_STR:
+            sli_memcpy(&(pb->val[0]), &(((pPmString_t)pobj)->val[0]), n);
+            break;
+
+        case OBJ_TYPE_LST:
+        case OBJ_TYPE_TUP:
+            for (i = 0; i < n; i++)
+            {
+                retval = seq_getSubscript(pobj, i, &pitem);
+                PM_RETURN_IF_ERROR(retval);
+                retval = bytes_getByteFromObj(pitem, &b);
+                PM_RETURN_IF_ERROR(retval);
+                pb->val[i] = b;
+            }
+            break;
+    }
+
+    *r_pobj = (pPmObj_t)pba;
+    return retval;
+}
+
+
+PmReturn_t
+bytearray_getItem(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj)
+{
+    PmReturn_t retval = PM_RET_OK;
+    pPmBytearray_t pba;
+    pPmBytes_t pb;
+    int32_t n;
+
+    pba = (pPmBytearray_t)pobj;
+
+    /* Adjust a negative index */
+    if (index < 0)
+    {
+        index += pba->length;
+    }
+
+    /* Check the bounds of the index */
+    if ((index < 0) || (index >= pba->length))
+    {
+        PM_RAISE(retval, PM_RET_EX_INDX);
+        return retval;
+    }
+
+    /* Create int from byte at index */
+    pb = pba->val;
+    n = (int32_t)pb->val[index];
+    retval = int_new(n, r_pobj);
+
+    return retval;
+}
+
+
+PmReturn_t
+bytearray_setItem(pPmObj_t pba, int16_t index, pPmObj_t pobj)
+{
+    PmReturn_t retval;
+    pPmBytes_t pb;
+    uint8_t b = 0;
+
+    /* Adjust a negative index */
+    if (index < 0)
+    {
+        index += ((pPmBytearray_t)pba)->length;
+    }
+
+    /* Check the bounds of the index */
+    if ((index < 0) || (index >= ((pPmBytearray_t)pba)->length))
+    {
+        PM_RAISE(retval, PM_RET_EX_INDX);
+        return retval;
+    }
+
+    /* Set the item */
+    retval = bytes_getByteFromObj(pobj, &b);
+    pb = ((pPmBytearray_t)pba)->val;
+    pb->val[index] = b;
+
+    return retval;
+}
+
+
+#ifdef HAVE_PRINT
+PmReturn_t
+bytearray_print(pPmObj_t pobj)
+{
+    PmReturn_t retval;
+    pPmBytes_t pb;
+
+    obj_print(PM_BYTEARRAY_STR, C_FALSE, C_FALSE);
+    plat_putByte('(');
+    plat_putByte('b');
+    pb = ((pPmBytearray_t)pobj)->val;
+    retval = string_printFormattedBytes(&(pb->val[0]),
+                                        C_TRUE,
+                                        ((pPmBytearray_t)pobj)->length);
+    plat_putByte(')');
+    return retval;
+}
+#endif /* HAVE_PRINT */
+#endif /* HAVE_BYTEARRAY */