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 # 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 00020 /** 00021 * \file 00022 * \brief Float Object Type 00023 * 00024 * Float object type operations. 00025 */ 00026 00027 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 } 00134 00135 /* Calculate x raised to y */ 00136 switch (op) 00137 { 00138 /* *INDENT-OFF* */ 00139 case '+': r = x + y; break; 00140 case '-': r = x - y; break; 00141 case '*': r = x * y; break; 00142 case '/': r = x / y; break; 00143 case '%': r = fmodf(x, y); break; 00144 case 'P': r = powf(x, y); break; 00145 default: r = 0.0; break; 00146 /* *INDENT-ON* */ 00147 } 00148 00149 retval = float_new(r, r_pn); 00150 00151 return retval; 00152 } 00153 00154 PmReturn_t 00155 float_compare(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pobj, PmCompare_t cmp) 00156 { 00157 float x; 00158 float y; 00159 PmReturn_t retval = PM_RET_OK; 00160 int8_t t8 = 0; 00161 00162 /* Raise TypeError if args aren't ints or floats */ 00163 if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) 00164 && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT)) 00165 || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT) 00166 && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT))) 00167 { 00168 PM_RAISE(retval, PM_RET_EX_TYPE); 00169 return retval; 00170 } 00171 00172 /* Get the values as floats */ 00173 if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT) 00174 { 00175 x = (float)((pPmInt_t)px)->val; 00176 } 00177 else 00178 { 00179 x = ((pPmFloat_t) px)->val; 00180 } 00181 00182 if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT) 00183 { 00184 y = (float)((pPmInt_t)py)->val; 00185 } 00186 else 00187 { 00188 y = ((pPmFloat_t) py)->val; 00189 } 00190 00191 switch (cmp) 00192 { 00193 /* *INDENT-OFF* */ 00194 case COMP_LT: t8 = (int8_t)(x < y); break; 00195 case COMP_LE: t8 = (int8_t)(x <= y); break; 00196 case COMP_EQ: t8 = (int8_t)(x == y); break; 00197 case COMP_NE: t8 = (int8_t)(x != y); break; 00198 case COMP_GT: t8 = (int8_t)(x > y); break; 00199 case COMP_GE: t8 = (int8_t)(x >= y); break; 00200 case COMP_IS: t8 = (int8_t)(px == py); break; 00201 case COMP_IS_NOT: t8 = (int8_t)(px != py);break; 00202 case COMP_IN: 00203 case COMP_NOT_IN: 00204 PM_RAISE(retval, PM_RET_EX_TYPE); 00205 break; 00206 00207 default: 00208 /* Other compares are not yet supported */ 00209 PM_RAISE(retval, PM_RET_EX_SYS); 00210 break; 00211 /* *INDENT-ON* */ 00212 } 00213 *r_pobj = (t8) ? PM_TRUE : PM_FALSE; 00214 00215 return retval; 00216 } 00217 00218 #endif /* HAVE_FLOAT */
Generated on Tue Jul 12 2022 17:07:01 by
1.7.2