float.c

Go to the documentation of this file.
00001 /*
00002 # This file is Copyright 2009, 2010 Dean Hall.
00003 #
00004 # This file is part of the PyMite VM.
00005 # The PyMite VM is free software: you can redistribute it and/or modify
00006 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
00007 #
00008 # The PyMite VM is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2
00012 # is seen in the file COPYING in this directory.
00013 */
00014 
00015 
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x17
00018 
00019 
00028 #include <math.h>
00029 #include "pm.h"
00030 
00031 
00032 #ifdef HAVE_FLOAT
00033 
00034 
00035 PmReturn_t
00036 float_new(float f, pPmObj_t *r_pf)
00037 {
00038     PmReturn_t retval = PM_RET_OK;
00039 
00040     retval = heap_getChunk(sizeof(PmFloat_t), (uint8_t **)r_pf);
00041     PM_RETURN_IF_ERROR(retval);
00042     OBJ_SET_TYPE(*r_pf, OBJ_TYPE_FLT);
00043     ((pPmFloat_t) * r_pf)->val = f;
00044     return retval;
00045 }
00046 
00047 
00048 #ifdef HAVE_PRINT
00049 PmReturn_t
00050 float_print(pPmObj_t pf)
00051 {
00052     uint8_t tBuffer[32];
00053     uint8_t bytesWritten;
00054     uint8_t i;
00055     PmReturn_t retval = PM_RET_OK;
00056 
00057     C_ASSERT(pf != C_NULL);
00058 
00059     /* Raise TypeError if obj is not an float */
00060     if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FLT)
00061     {
00062         PM_RAISE(retval, PM_RET_EX_TYPE);
00063         return retval;
00064     }
00065 
00066     /* #196: Changed to use snprintf */
00067     bytesWritten = snprintf((char *)&tBuffer, 32, "%f", ((pPmFloat_t) pf)->val);
00068 
00069     /* Sanity check */
00070     C_ASSERT(bytesWritten != 0);
00071     C_ASSERT(bytesWritten < sizeof(tBuffer));
00072 
00073     for (i = (uint8_t)0; i < bytesWritten; i++)
00074     {
00075         retval = plat_putByte(tBuffer[i]);
00076         PM_RETURN_IF_ERROR(retval);
00077     }
00078     return PM_RET_OK;
00079 }
00080 
00081 
00082 PmReturn_t
00083 float_negative(pPmObj_t pf, pPmObj_t *r_pf)
00084 {
00085     /* Create new int obj */
00086     return float_new(-((pPmFloat_t) pf)->val, r_pf);
00087 }
00088 
00089 #endif /* HAVE_PRINT */
00090 
00091 
00092 PmReturn_t
00093 float_op(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn, int8_t op)
00094 {
00095     float x;
00096     float y;
00097     float r;
00098     PmReturn_t retval;
00099 
00100     /* Raise TypeError if args aren't ints or floats */
00101     if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
00102          && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT))
00103         || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT)
00104             && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT)))
00105     {
00106         PM_RAISE(retval, PM_RET_EX_TYPE);
00107         return retval;
00108     }
00109 
00110     /* Get the values as floats */
00111     if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT)
00112     {
00113         x = (float)((pPmInt_t)px)->val;
00114     }
00115     else
00116     {
00117         x = ((pPmFloat_t) px)->val;
00118     }
00119 
00120     if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT)
00121     {
00122         y = (float)((pPmInt_t)py)->val;
00123     }
00124     else
00125     {
00126         y = ((pPmFloat_t) py)->val;
00127     }
00128 
00129     /* Raise ZeroDivisionError if denominator is zero */
00130     if ((y == 0.0) && ((op == '/') || (op == '%')))
00131     {
00132         PM_RAISE(retval, PM_RET_EX_ZDIV);
00133         return retval;
00134     }
00135 
00136     /* Calculate x raised to y */
00137     switch (op)
00138     {
00139         /* *INDENT-OFF* */
00140         case '+': r = x + y; break;
00141         case '-': r = x - y; break;
00142         case '*': r = x * y; break;
00143         case '/': r = x / y; break;
00144         case '%': r = fmodf(x, y); break;
00145         case 'P': r = powf(x, y); break;
00146         default: r = 0.0; break;
00147         /* *INDENT-ON* */
00148     }
00149 
00150     retval = float_new(r, r_pn);
00151 
00152     return retval;
00153 }
00154 
00155 PmReturn_t
00156 float_compare(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pobj, PmCompare_t cmp)
00157 {
00158     float x;
00159     float y;
00160     PmReturn_t retval = PM_RET_OK;
00161     int8_t t8 = 0;
00162 
00163     /* Raise TypeError if args aren't ints or floats */
00164     if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
00165          && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT))
00166         || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT)
00167             && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT)))
00168     {
00169         PM_RAISE(retval, PM_RET_EX_TYPE);
00170         return retval;
00171     }
00172 
00173     /* Get the values as floats */
00174     if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT)
00175     {
00176         x = (float)((pPmInt_t)px)->val;
00177     }
00178     else
00179     {
00180         x = ((pPmFloat_t) px)->val;
00181     }
00182 
00183     if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT)
00184     {
00185         y = (float)((pPmInt_t)py)->val;
00186     }
00187     else
00188     {
00189         y = ((pPmFloat_t) py)->val;
00190     }
00191 
00192     switch (cmp)
00193     {
00194         /* *INDENT-OFF* */
00195         case COMP_LT: t8 = (int8_t)(x <  y); break;
00196         case COMP_LE: t8 = (int8_t)(x <= y); break;
00197         case COMP_EQ: t8 = (int8_t)(x == y); break;
00198         case COMP_NE: t8 = (int8_t)(x != y); break;
00199         case COMP_GT: t8 = (int8_t)(x >  y); break;
00200         case COMP_GE: t8 = (int8_t)(x >= y); break;
00201         case COMP_IS: t8 = (int8_t)(px == py); break;
00202         case COMP_IS_NOT: t8 = (int8_t)(px != py);break;
00203         case COMP_IN:
00204         case COMP_NOT_IN:
00205             PM_RAISE(retval, PM_RET_EX_TYPE);
00206             break;
00207 
00208         default:
00209             /* Other compares are not yet supported */
00210             PM_RAISE(retval, PM_RET_EX_SYS);
00211             break;
00212         /* *INDENT-ON* */
00213     }
00214     *r_pobj = (t8) ? PM_TRUE : PM_FALSE;
00215 
00216     return retval;
00217 }
00218 
00219 #endif /* HAVE_FLOAT */

Generated on Mon Oct 18 07:40:47 2010 for Python-on-a-chip by  doxygen 1.5.9