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/int.c	Sat Mar 02 11:54:20 2013 +0000
@@ -0,0 +1,272 @@
+/*
+# 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__ 0x08
+
+
+/**
+ * \file
+ * \brief Integer Object Type
+ *
+ * Integer object type operations.
+ */
+
+#include <limits.h>
+
+#include "pm.h"
+
+
+PmReturn_t
+int_dup(pPmObj_t pint, pPmObj_t *r_pint)
+{
+    PmReturn_t retval = PM_RET_OK;
+
+    /* Allocate new int */
+    retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Copy value */
+    OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT);
+    ((pPmInt_t)*r_pint)->val = ((pPmInt_t)pint)->val;
+    return retval;
+}
+
+
+PmReturn_t
+int_new(int32_t n, pPmObj_t *r_pint)
+{
+    PmReturn_t retval = PM_RET_OK;
+
+    /* If n is 0,1,-1, return static int objects from global struct */
+    if (n == 0)
+    {
+        *r_pint = PM_ZERO;
+        return PM_RET_OK;
+    }
+    if (n == 1)
+    {
+        *r_pint = PM_ONE;
+        return PM_RET_OK;
+    }
+    if (n == -1)
+    {
+        *r_pint = PM_NEGONE;
+        return PM_RET_OK;
+    }
+
+    /* Else create and return new int obj */
+    retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint);
+    PM_RETURN_IF_ERROR(retval);
+    OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT);
+    ((pPmInt_t)*r_pint)->val = n;
+    return retval;
+}
+
+
+PmReturn_t
+int_positive(pPmObj_t pobj, pPmObj_t *r_pint)
+{
+    PmReturn_t retval;
+
+    /* Raise TypeError if obj is not an int */
+    if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Create new int obj */
+    return int_new(((pPmInt_t)pobj)->val, r_pint);
+}
+
+
+PmReturn_t
+int_negative(pPmObj_t pobj, pPmObj_t *r_pint)
+{
+    PmReturn_t retval;
+
+    /* Raise TypeError if obj is not an int */
+    if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Create new int obj */
+    return int_new(-((pPmInt_t)pobj)->val, r_pint);
+}
+
+
+PmReturn_t
+int_bitInvert(pPmObj_t pobj, pPmObj_t *r_pint)
+{
+    PmReturn_t retval;
+
+    /* Raise TypeError if obj is not an int */
+    if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Create new int obj */
+    return int_new(~((pPmInt_t)pobj)->val, r_pint);
+}
+
+
+PmReturn_t
+int_print(pPmObj_t pint)
+{
+    PmReturn_t retval = PM_RET_OK;
+    uint8_t buf[12];
+
+    C_ASSERT(pint != C_NULL);
+
+    /* Raise TypeError if obj is not an int */
+    if (OBJ_GET_TYPE(pint) != OBJ_TYPE_INT)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    retval = sli_ltoa10(((pPmInt_t)pint)->val, buf, sizeof(buf));
+    PM_RETURN_IF_ERROR(retval);
+    sli_puts(buf);
+
+    return retval;
+}
+
+
+PmReturn_t
+int_printHex(pPmObj_t pint)
+{
+    uint8_t buf[9];
+    PmReturn_t retval = PM_RET_OK;
+
+    C_ASSERT(OBJ_GET_TYPE(pint) == OBJ_TYPE_INT);
+
+    /* Print the integer object */
+    retval = sli_ltoa16(((pPmInt_t)pint)->val, buf, sizeof(buf), 1);
+    sli_puts(buf);
+    return retval;
+}
+
+
+PmReturn_t
+int_pow(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn)
+{
+    int32_t x;
+    int32_t y;
+    int32_t n;
+    PmReturn_t retval;
+
+    /* Raise TypeError if args aren't ints */
+    if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
+        || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    x = ((pPmInt_t)px)->val;
+    y = ((pPmInt_t)py)->val;
+
+    /* Raise Value error if exponent is negative */
+    if (y < 0)
+    {
+        PM_RAISE(retval, PM_RET_EX_VAL);
+        return retval;
+    }
+
+    /* Calculate x raised to y */
+    n = 1;
+    while (y > 0)
+    {
+        n = n * x;
+        y--;
+    }
+    retval = int_new(n, r_pn);
+
+    return retval;
+}
+
+
+PmReturn_t
+int_divmod(pPmObj_t px, pPmObj_t py, uint8_t op, pPmObj_t *r_pxopy)
+{
+    int32_t x;
+    int32_t y;
+    int32_t xdivy;
+    int32_t xmody;
+    int32_t xopy;
+    PmReturn_t retval = PM_RET_OK;
+
+    /* Raise TypeError if args aren't ints */
+    if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
+        || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    x = ((pPmInt_t)px)->val;
+    y = ((pPmInt_t)py)->val;
+
+    /* Raise ZeroDivisionError if denominator is zero */
+    if (y == 0)
+    {
+        PM_RAISE(retval, PM_RET_EX_ZDIV);
+        return retval;
+    }
+
+    /* Issue #167: Make overflow silent until exceptions can be caught */
+    /* (-sys.maxint-1)/-1 is the only overflow case. */
+    /* TODO:  enable the overflow for Issue #169 */
+    /*
+    if ((y == -1) && (op == '/') && (x < 0)
+        && ((uint32_t)x == (0 - (uint32_t)x)))
+    {
+        PM_RAISE(retval, PM_RET_EX_OFLOW);
+        return retval;
+    }
+    */
+
+    /* Shortcut when denominator is one or negative one */
+    if (y == 1)
+    {
+        xdivy = x;
+        xmody = 0;
+    }
+    else if (y == -1)
+    {
+        xdivy = -x;
+        xmody = 0;
+    }
+
+    else
+    {
+        xdivy = x / y;
+        xmody = x - xdivy * y;
+
+        /*
+         * If the remainder is non-0 and the signs of x and y differ,
+         * C89 doesn't define whether xdivy is now the floor or the
+         * ceiling of the infinitely precise quotient.  We want the floor,
+         * and we have it iff the remainder's sign matches y's.
+         */
+        if ((xmody != 0) && ((y ^ xmody) < 0))
+        {
+            xmody += y;
+            --xdivy;
+            C_ASSERT(xmody && ((y ^ xmody) >= 0));
+        }
+    }
+    xopy = (op == '/') ? xdivy : xmody;
+    return int_new(xopy, r_pxopy);
+}