Norimasa Okamoto
/
pymite
python-on-a-chip online compiler
Embed:
(wiki syntax)
Show/hide line numbers
float.c
Go to the documentation of this file.
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