Norimasa Okamoto
/
pymite
python-on-a-chip online compiler
- http://pymbed.appspot.com/
- https://code.google.com/p/python-on-a-chip/
- http://www.youtube.com/watch?v=Oyqc2bFRW9I
- https://bitbucket.org/va009039/pymbed/
more info: python-on-a-chip
Diff: vm/float.c
- 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 */