Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
float.c
00001 /* 00002 # This file is Copyright 2009 Dean Hall. 00003 # This file is part of the PyMite VM. 00004 # This file is licensed under the MIT License. 00005 # See the LICENSE file for details. 00006 */ 00007 00008 00009 #undef __FILE_ID__ 00010 #define __FILE_ID__ 0x17 00011 00012 00013 /** 00014 * \file 00015 * \brief Float Object Type 00016 * 00017 * Float object type operations. 00018 */ 00019 00020 00021 #include "pm.h" 00022 00023 00024 #ifdef HAVE_FLOAT 00025 #include <math.h> 00026 00027 00028 PmReturn_t 00029 float_new(float f, pPmObj_t *r_pf) 00030 { 00031 PmReturn_t retval = PM_RET_OK; 00032 00033 retval = heap_getChunk(sizeof(PmFloat_t), (uint8_t **)r_pf); 00034 PM_RETURN_IF_ERROR(retval); 00035 OBJ_SET_TYPE(*r_pf, OBJ_TYPE_FLT); 00036 ((pPmFloat_t) * r_pf)->val = f; 00037 return retval; 00038 } 00039 00040 00041 #ifdef HAVE_PRINT 00042 00043 PmReturn_t 00044 float_print(pPmObj_t pf) 00045 { 00046 uint8_t tBuffer[32]; 00047 uint8_t bytesWritten; 00048 uint8_t *p; 00049 PmReturn_t retval = PM_RET_OK; 00050 00051 C_ASSERT(pf != C_NULL); 00052 00053 /* Raise TypeError if obj is not an float */ 00054 if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FLT) 00055 { 00056 PM_RAISE(retval, PM_RET_EX_TYPE); 00057 return retval; 00058 } 00059 00060 /* #212: Use homebrew float formatter */ 00061 retval = sli_ftoa(((pPmFloat_t)pf)->val, tBuffer, sizeof(tBuffer)); 00062 bytesWritten = sli_strlen((char *)tBuffer); 00063 00064 /* Remove trailing zeroes (per Python convention) */ 00065 for (p = &tBuffer[bytesWritten] - 1; 00066 p[0] == '0' && p[-1] != '.'; 00067 --p, bytesWritten--); 00068 ++p; 00069 *p = '\0'; 00070 00071 /* Sanity check */ 00072 C_ASSERT(bytesWritten != 0); 00073 C_ASSERT(bytesWritten < sizeof(tBuffer)); 00074 00075 sli_puts(tBuffer); 00076 return PM_RET_OK; 00077 } 00078 00079 00080 PmReturn_t 00081 float_negative(pPmObj_t pf, pPmObj_t *r_pf) 00082 { 00083 /* Create new int obj */ 00084 return float_new(-((pPmFloat_t) pf)->val, r_pf); 00085 } 00086 00087 #endif /* HAVE_PRINT */ 00088 00089 00090 PmReturn_t 00091 float_op(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn, int8_t op) 00092 { 00093 float x; 00094 float y; 00095 float r; 00096 PmReturn_t retval; 00097 00098 /* Raise TypeError if args aren't ints or floats */ 00099 if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) 00100 && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT)) 00101 || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT) 00102 && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT))) 00103 { 00104 PM_RAISE(retval, PM_RET_EX_TYPE); 00105 return retval; 00106 } 00107 00108 /* Get the values as floats */ 00109 if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT) 00110 { 00111 x = (float)((pPmInt_t)px)->val; 00112 } 00113 else 00114 { 00115 x = ((pPmFloat_t) px)->val; 00116 } 00117 00118 if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT) 00119 { 00120 y = (float)((pPmInt_t)py)->val; 00121 } 00122 else 00123 { 00124 y = ((pPmFloat_t) py)->val; 00125 } 00126 00127 /* Raise ZeroDivisionError if denominator is zero */ 00128 if ((y == 0.0) && ((op == '/') || (op == '%'))) 00129 { 00130 PM_RAISE(retval, PM_RET_EX_ZDIV); 00131 return retval; 00132 } 00133 00134 /* Calculate x raised to y */ 00135 switch (op) 00136 { 00137 /* *INDENT-OFF* */ 00138 case '+': r = x + y; break; 00139 case '-': r = x - y; break; 00140 case '*': r = x * y; break; 00141 case '/': r = x / y; break; 00142 case '%': r = fmodf(x, y); break; 00143 case 'P': r = powf(x, y); break; 00144 default: r = 0.0; break; 00145 /* *INDENT-ON* */ 00146 } 00147 00148 retval = float_new(r, r_pn); 00149 00150 return retval; 00151 } 00152 00153 PmReturn_t 00154 float_compare(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pobj, PmCompare_t cmp) 00155 { 00156 float x; 00157 float y; 00158 PmReturn_t retval = PM_RET_OK; 00159 int8_t t8 = 0; 00160 00161 /* Raise TypeError if args aren't ints or floats */ 00162 if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) 00163 && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT)) 00164 || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT) 00165 && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT))) 00166 { 00167 PM_RAISE(retval, PM_RET_EX_TYPE); 00168 return retval; 00169 } 00170 00171 /* Get the values as floats */ 00172 if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT) 00173 { 00174 x = (float)((pPmInt_t)px)->val; 00175 } 00176 else 00177 { 00178 x = ((pPmFloat_t) px)->val; 00179 } 00180 00181 if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT) 00182 { 00183 y = (float)((pPmInt_t)py)->val; 00184 } 00185 else 00186 { 00187 y = ((pPmFloat_t) py)->val; 00188 } 00189 00190 switch (cmp) 00191 { 00192 /* *INDENT-OFF* */ 00193 case COMP_LT: t8 = (int8_t)(x < y); break; 00194 case COMP_LE: t8 = (int8_t)(x <= y); break; 00195 case COMP_EQ: t8 = (int8_t)(x == y); break; 00196 case COMP_NE: t8 = (int8_t)(x != y); break; 00197 case COMP_GT: t8 = (int8_t)(x > y); break; 00198 case COMP_GE: t8 = (int8_t)(x >= y); break; 00199 case COMP_IS: t8 = (int8_t)(px == py); break; 00200 case COMP_IS_NOT: t8 = (int8_t)(px != py);break; 00201 case COMP_IN: 00202 case COMP_NOT_IN: 00203 PM_RAISE(retval, PM_RET_EX_TYPE); 00204 break; 00205 00206 default: 00207 /* Other compares are not yet supported */ 00208 PM_RAISE(retval, PM_RET_EX_SYS); 00209 break; 00210 /* *INDENT-ON* */ 00211 } 00212 *r_pobj = (t8) ? PM_TRUE : PM_FALSE; 00213 00214 return retval; 00215 } 00216 00217 #endif /* HAVE_FLOAT */
Generated on Tue Jul 12 2022 23:13:47 by
1.7.2