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
vm/float.c
- Committer:
- va009039
- Date:
- 2016-04-14
- Revision:
- 15:94ca5c8003e5
- Parent:
- 0:65f1469d6bfb
File content as of revision 15:94ca5c8003e5:
/* # 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 */