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/float.c	Sat Mar 02 11:54:20 2013 +0000
@@ -0,0 +1,217 @@
+/*
+# This file is Copyright 2009 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__ 0x17
+
+
+/**
+ * \file
+ * \brief Float Object Type
+ *
+ * Float object type operations.
+ */
+
+
+#include "pm.h"
+
+
+#ifdef HAVE_FLOAT
+#include <math.h>
+
+
+PmReturn_t
+float_new(float f, pPmObj_t *r_pf)
+{
+    PmReturn_t retval = PM_RET_OK;
+
+    retval = heap_getChunk(sizeof(PmFloat_t), (uint8_t **)r_pf);
+    PM_RETURN_IF_ERROR(retval);
+    OBJ_SET_TYPE(*r_pf, OBJ_TYPE_FLT);
+    ((pPmFloat_t) * r_pf)->val = f;
+    return retval;
+}
+
+
+#ifdef HAVE_PRINT
+
+PmReturn_t
+float_print(pPmObj_t pf)
+{
+    uint8_t tBuffer[32];
+    uint8_t bytesWritten;
+    uint8_t *p;
+    PmReturn_t retval = PM_RET_OK;
+
+    C_ASSERT(pf != C_NULL);
+
+    /* Raise TypeError if obj is not an float */
+    if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FLT)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* #212: Use homebrew float formatter */
+    retval = sli_ftoa(((pPmFloat_t)pf)->val, tBuffer, sizeof(tBuffer));
+    bytesWritten = sli_strlen((char *)tBuffer);
+
+    /* Remove trailing zeroes (per Python convention) */
+    for (p = &tBuffer[bytesWritten] - 1; 
+         p[0] == '0' && p[-1] != '.'; 
+         --p, bytesWritten--);
+    ++p;
+    *p = '\0';
+
+    /* Sanity check */
+    C_ASSERT(bytesWritten != 0);
+    C_ASSERT(bytesWritten < sizeof(tBuffer));
+
+    sli_puts(tBuffer);
+    return PM_RET_OK;
+}
+
+
+PmReturn_t
+float_negative(pPmObj_t pf, pPmObj_t *r_pf)
+{
+    /* Create new int obj */
+    return float_new(-((pPmFloat_t) pf)->val, r_pf);
+}
+
+#endif /* HAVE_PRINT */
+
+
+PmReturn_t
+float_op(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn, int8_t op)
+{
+    float x;
+    float y;
+    float r;
+    PmReturn_t retval;
+
+    /* Raise TypeError if args aren't ints or floats */
+    if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
+         && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT))
+        || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT)
+            && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT)))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Get the values as floats */
+    if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT)
+    {
+        x = (float)((pPmInt_t)px)->val;
+    }
+    else
+    {
+        x = ((pPmFloat_t) px)->val;
+    }
+
+    if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT)
+    {
+        y = (float)((pPmInt_t)py)->val;
+    }
+    else
+    {
+        y = ((pPmFloat_t) py)->val;
+    }
+
+    /* Raise ZeroDivisionError if denominator is zero */
+    if ((y == 0.0) && ((op == '/') || (op == '%')))
+    {
+        PM_RAISE(retval, PM_RET_EX_ZDIV);
+        return retval;
+    }
+
+    /* Calculate x raised to y */
+    switch (op)
+    {
+        /* *INDENT-OFF* */
+        case '+': r = x + y; break;
+        case '-': r = x - y; break;
+        case '*': r = x * y; break;
+        case '/': r = x / y; break;
+        case '%': r = fmodf(x, y); break;
+        case 'P': r = powf(x, y); break;
+        default: r = 0.0; break;
+        /* *INDENT-ON* */
+    }
+
+    retval = float_new(r, r_pn);
+
+    return retval;
+}
+
+PmReturn_t
+float_compare(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pobj, PmCompare_t cmp)
+{
+    float x;
+    float y;
+    PmReturn_t retval = PM_RET_OK;
+    int8_t t8 = 0;
+
+    /* Raise TypeError if args aren't ints or floats */
+    if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
+         && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT))
+        || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT)
+            && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT)))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Get the values as floats */
+    if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT)
+    {
+        x = (float)((pPmInt_t)px)->val;
+    }
+    else
+    {
+        x = ((pPmFloat_t) px)->val;
+    }
+
+    if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT)
+    {
+        y = (float)((pPmInt_t)py)->val;
+    }
+    else
+    {
+        y = ((pPmFloat_t) py)->val;
+    }
+
+    switch (cmp)
+    {
+        /* *INDENT-OFF* */
+        case COMP_LT: t8 = (int8_t)(x <  y); break;
+        case COMP_LE: t8 = (int8_t)(x <= y); break;
+        case COMP_EQ: t8 = (int8_t)(x == y); break;
+        case COMP_NE: t8 = (int8_t)(x != y); break;
+        case COMP_GT: t8 = (int8_t)(x >  y); break;
+        case COMP_GE: t8 = (int8_t)(x >= y); break;
+        case COMP_IS: t8 = (int8_t)(px == py); break;
+        case COMP_IS_NOT: t8 = (int8_t)(px != py);break;
+        case COMP_IN:
+        case COMP_NOT_IN:
+            PM_RAISE(retval, PM_RET_EX_TYPE);
+            break;
+
+        default:
+            /* Other compares are not yet supported */
+            PM_RAISE(retval, PM_RET_EX_SYS);
+            break;
+        /* *INDENT-ON* */
+    }
+    *r_pobj = (t8) ? PM_TRUE : PM_FALSE;
+
+    return retval;
+}
+
+#endif /* HAVE_FLOAT */