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@0:65f1469d6bfb, 2013-03-02 (annotated)
- Committer:
- va009039
- Date:
- Sat Mar 02 11:54:20 2013 +0000
- Revision:
- 0:65f1469d6bfb
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:65f1469d6bfb | 1 | /* |
va009039 | 0:65f1469d6bfb | 2 | # This file is Copyright 2009 Dean Hall. |
va009039 | 0:65f1469d6bfb | 3 | # This file is part of the PyMite VM. |
va009039 | 0:65f1469d6bfb | 4 | # This file is licensed under the MIT License. |
va009039 | 0:65f1469d6bfb | 5 | # See the LICENSE file for details. |
va009039 | 0:65f1469d6bfb | 6 | */ |
va009039 | 0:65f1469d6bfb | 7 | |
va009039 | 0:65f1469d6bfb | 8 | |
va009039 | 0:65f1469d6bfb | 9 | #undef __FILE_ID__ |
va009039 | 0:65f1469d6bfb | 10 | #define __FILE_ID__ 0x17 |
va009039 | 0:65f1469d6bfb | 11 | |
va009039 | 0:65f1469d6bfb | 12 | |
va009039 | 0:65f1469d6bfb | 13 | /** |
va009039 | 0:65f1469d6bfb | 14 | * \file |
va009039 | 0:65f1469d6bfb | 15 | * \brief Float Object Type |
va009039 | 0:65f1469d6bfb | 16 | * |
va009039 | 0:65f1469d6bfb | 17 | * Float object type operations. |
va009039 | 0:65f1469d6bfb | 18 | */ |
va009039 | 0:65f1469d6bfb | 19 | |
va009039 | 0:65f1469d6bfb | 20 | |
va009039 | 0:65f1469d6bfb | 21 | #include "pm.h" |
va009039 | 0:65f1469d6bfb | 22 | |
va009039 | 0:65f1469d6bfb | 23 | |
va009039 | 0:65f1469d6bfb | 24 | #ifdef HAVE_FLOAT |
va009039 | 0:65f1469d6bfb | 25 | #include <math.h> |
va009039 | 0:65f1469d6bfb | 26 | |
va009039 | 0:65f1469d6bfb | 27 | |
va009039 | 0:65f1469d6bfb | 28 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 29 | float_new(float f, pPmObj_t *r_pf) |
va009039 | 0:65f1469d6bfb | 30 | { |
va009039 | 0:65f1469d6bfb | 31 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 32 | |
va009039 | 0:65f1469d6bfb | 33 | retval = heap_getChunk(sizeof(PmFloat_t), (uint8_t **)r_pf); |
va009039 | 0:65f1469d6bfb | 34 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 35 | OBJ_SET_TYPE(*r_pf, OBJ_TYPE_FLT); |
va009039 | 0:65f1469d6bfb | 36 | ((pPmFloat_t) * r_pf)->val = f; |
va009039 | 0:65f1469d6bfb | 37 | return retval; |
va009039 | 0:65f1469d6bfb | 38 | } |
va009039 | 0:65f1469d6bfb | 39 | |
va009039 | 0:65f1469d6bfb | 40 | |
va009039 | 0:65f1469d6bfb | 41 | #ifdef HAVE_PRINT |
va009039 | 0:65f1469d6bfb | 42 | |
va009039 | 0:65f1469d6bfb | 43 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 44 | float_print(pPmObj_t pf) |
va009039 | 0:65f1469d6bfb | 45 | { |
va009039 | 0:65f1469d6bfb | 46 | uint8_t tBuffer[32]; |
va009039 | 0:65f1469d6bfb | 47 | uint8_t bytesWritten; |
va009039 | 0:65f1469d6bfb | 48 | uint8_t *p; |
va009039 | 0:65f1469d6bfb | 49 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 50 | |
va009039 | 0:65f1469d6bfb | 51 | C_ASSERT(pf != C_NULL); |
va009039 | 0:65f1469d6bfb | 52 | |
va009039 | 0:65f1469d6bfb | 53 | /* Raise TypeError if obj is not an float */ |
va009039 | 0:65f1469d6bfb | 54 | if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FLT) |
va009039 | 0:65f1469d6bfb | 55 | { |
va009039 | 0:65f1469d6bfb | 56 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 57 | return retval; |
va009039 | 0:65f1469d6bfb | 58 | } |
va009039 | 0:65f1469d6bfb | 59 | |
va009039 | 0:65f1469d6bfb | 60 | /* #212: Use homebrew float formatter */ |
va009039 | 0:65f1469d6bfb | 61 | retval = sli_ftoa(((pPmFloat_t)pf)->val, tBuffer, sizeof(tBuffer)); |
va009039 | 0:65f1469d6bfb | 62 | bytesWritten = sli_strlen((char *)tBuffer); |
va009039 | 0:65f1469d6bfb | 63 | |
va009039 | 0:65f1469d6bfb | 64 | /* Remove trailing zeroes (per Python convention) */ |
va009039 | 0:65f1469d6bfb | 65 | for (p = &tBuffer[bytesWritten] - 1; |
va009039 | 0:65f1469d6bfb | 66 | p[0] == '0' && p[-1] != '.'; |
va009039 | 0:65f1469d6bfb | 67 | --p, bytesWritten--); |
va009039 | 0:65f1469d6bfb | 68 | ++p; |
va009039 | 0:65f1469d6bfb | 69 | *p = '\0'; |
va009039 | 0:65f1469d6bfb | 70 | |
va009039 | 0:65f1469d6bfb | 71 | /* Sanity check */ |
va009039 | 0:65f1469d6bfb | 72 | C_ASSERT(bytesWritten != 0); |
va009039 | 0:65f1469d6bfb | 73 | C_ASSERT(bytesWritten < sizeof(tBuffer)); |
va009039 | 0:65f1469d6bfb | 74 | |
va009039 | 0:65f1469d6bfb | 75 | sli_puts(tBuffer); |
va009039 | 0:65f1469d6bfb | 76 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 77 | } |
va009039 | 0:65f1469d6bfb | 78 | |
va009039 | 0:65f1469d6bfb | 79 | |
va009039 | 0:65f1469d6bfb | 80 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 81 | float_negative(pPmObj_t pf, pPmObj_t *r_pf) |
va009039 | 0:65f1469d6bfb | 82 | { |
va009039 | 0:65f1469d6bfb | 83 | /* Create new int obj */ |
va009039 | 0:65f1469d6bfb | 84 | return float_new(-((pPmFloat_t) pf)->val, r_pf); |
va009039 | 0:65f1469d6bfb | 85 | } |
va009039 | 0:65f1469d6bfb | 86 | |
va009039 | 0:65f1469d6bfb | 87 | #endif /* HAVE_PRINT */ |
va009039 | 0:65f1469d6bfb | 88 | |
va009039 | 0:65f1469d6bfb | 89 | |
va009039 | 0:65f1469d6bfb | 90 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 91 | float_op(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn, int8_t op) |
va009039 | 0:65f1469d6bfb | 92 | { |
va009039 | 0:65f1469d6bfb | 93 | float x; |
va009039 | 0:65f1469d6bfb | 94 | float y; |
va009039 | 0:65f1469d6bfb | 95 | float r; |
va009039 | 0:65f1469d6bfb | 96 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 97 | |
va009039 | 0:65f1469d6bfb | 98 | /* Raise TypeError if args aren't ints or floats */ |
va009039 | 0:65f1469d6bfb | 99 | if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 100 | && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT)) |
va009039 | 0:65f1469d6bfb | 101 | || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 102 | && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT))) |
va009039 | 0:65f1469d6bfb | 103 | { |
va009039 | 0:65f1469d6bfb | 104 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 105 | return retval; |
va009039 | 0:65f1469d6bfb | 106 | } |
va009039 | 0:65f1469d6bfb | 107 | |
va009039 | 0:65f1469d6bfb | 108 | /* Get the values as floats */ |
va009039 | 0:65f1469d6bfb | 109 | if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 110 | { |
va009039 | 0:65f1469d6bfb | 111 | x = (float)((pPmInt_t)px)->val; |
va009039 | 0:65f1469d6bfb | 112 | } |
va009039 | 0:65f1469d6bfb | 113 | else |
va009039 | 0:65f1469d6bfb | 114 | { |
va009039 | 0:65f1469d6bfb | 115 | x = ((pPmFloat_t) px)->val; |
va009039 | 0:65f1469d6bfb | 116 | } |
va009039 | 0:65f1469d6bfb | 117 | |
va009039 | 0:65f1469d6bfb | 118 | if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 119 | { |
va009039 | 0:65f1469d6bfb | 120 | y = (float)((pPmInt_t)py)->val; |
va009039 | 0:65f1469d6bfb | 121 | } |
va009039 | 0:65f1469d6bfb | 122 | else |
va009039 | 0:65f1469d6bfb | 123 | { |
va009039 | 0:65f1469d6bfb | 124 | y = ((pPmFloat_t) py)->val; |
va009039 | 0:65f1469d6bfb | 125 | } |
va009039 | 0:65f1469d6bfb | 126 | |
va009039 | 0:65f1469d6bfb | 127 | /* Raise ZeroDivisionError if denominator is zero */ |
va009039 | 0:65f1469d6bfb | 128 | if ((y == 0.0) && ((op == '/') || (op == '%'))) |
va009039 | 0:65f1469d6bfb | 129 | { |
va009039 | 0:65f1469d6bfb | 130 | PM_RAISE(retval, PM_RET_EX_ZDIV); |
va009039 | 0:65f1469d6bfb | 131 | return retval; |
va009039 | 0:65f1469d6bfb | 132 | } |
va009039 | 0:65f1469d6bfb | 133 | |
va009039 | 0:65f1469d6bfb | 134 | /* Calculate x raised to y */ |
va009039 | 0:65f1469d6bfb | 135 | switch (op) |
va009039 | 0:65f1469d6bfb | 136 | { |
va009039 | 0:65f1469d6bfb | 137 | /* *INDENT-OFF* */ |
va009039 | 0:65f1469d6bfb | 138 | case '+': r = x + y; break; |
va009039 | 0:65f1469d6bfb | 139 | case '-': r = x - y; break; |
va009039 | 0:65f1469d6bfb | 140 | case '*': r = x * y; break; |
va009039 | 0:65f1469d6bfb | 141 | case '/': r = x / y; break; |
va009039 | 0:65f1469d6bfb | 142 | case '%': r = fmodf(x, y); break; |
va009039 | 0:65f1469d6bfb | 143 | case 'P': r = powf(x, y); break; |
va009039 | 0:65f1469d6bfb | 144 | default: r = 0.0; break; |
va009039 | 0:65f1469d6bfb | 145 | /* *INDENT-ON* */ |
va009039 | 0:65f1469d6bfb | 146 | } |
va009039 | 0:65f1469d6bfb | 147 | |
va009039 | 0:65f1469d6bfb | 148 | retval = float_new(r, r_pn); |
va009039 | 0:65f1469d6bfb | 149 | |
va009039 | 0:65f1469d6bfb | 150 | return retval; |
va009039 | 0:65f1469d6bfb | 151 | } |
va009039 | 0:65f1469d6bfb | 152 | |
va009039 | 0:65f1469d6bfb | 153 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 154 | float_compare(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pobj, PmCompare_t cmp) |
va009039 | 0:65f1469d6bfb | 155 | { |
va009039 | 0:65f1469d6bfb | 156 | float x; |
va009039 | 0:65f1469d6bfb | 157 | float y; |
va009039 | 0:65f1469d6bfb | 158 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 159 | int8_t t8 = 0; |
va009039 | 0:65f1469d6bfb | 160 | |
va009039 | 0:65f1469d6bfb | 161 | /* Raise TypeError if args aren't ints or floats */ |
va009039 | 0:65f1469d6bfb | 162 | if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 163 | && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT)) |
va009039 | 0:65f1469d6bfb | 164 | || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 165 | && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT))) |
va009039 | 0:65f1469d6bfb | 166 | { |
va009039 | 0:65f1469d6bfb | 167 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 168 | return retval; |
va009039 | 0:65f1469d6bfb | 169 | } |
va009039 | 0:65f1469d6bfb | 170 | |
va009039 | 0:65f1469d6bfb | 171 | /* Get the values as floats */ |
va009039 | 0:65f1469d6bfb | 172 | if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 173 | { |
va009039 | 0:65f1469d6bfb | 174 | x = (float)((pPmInt_t)px)->val; |
va009039 | 0:65f1469d6bfb | 175 | } |
va009039 | 0:65f1469d6bfb | 176 | else |
va009039 | 0:65f1469d6bfb | 177 | { |
va009039 | 0:65f1469d6bfb | 178 | x = ((pPmFloat_t) px)->val; |
va009039 | 0:65f1469d6bfb | 179 | } |
va009039 | 0:65f1469d6bfb | 180 | |
va009039 | 0:65f1469d6bfb | 181 | if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 182 | { |
va009039 | 0:65f1469d6bfb | 183 | y = (float)((pPmInt_t)py)->val; |
va009039 | 0:65f1469d6bfb | 184 | } |
va009039 | 0:65f1469d6bfb | 185 | else |
va009039 | 0:65f1469d6bfb | 186 | { |
va009039 | 0:65f1469d6bfb | 187 | y = ((pPmFloat_t) py)->val; |
va009039 | 0:65f1469d6bfb | 188 | } |
va009039 | 0:65f1469d6bfb | 189 | |
va009039 | 0:65f1469d6bfb | 190 | switch (cmp) |
va009039 | 0:65f1469d6bfb | 191 | { |
va009039 | 0:65f1469d6bfb | 192 | /* *INDENT-OFF* */ |
va009039 | 0:65f1469d6bfb | 193 | case COMP_LT: t8 = (int8_t)(x < y); break; |
va009039 | 0:65f1469d6bfb | 194 | case COMP_LE: t8 = (int8_t)(x <= y); break; |
va009039 | 0:65f1469d6bfb | 195 | case COMP_EQ: t8 = (int8_t)(x == y); break; |
va009039 | 0:65f1469d6bfb | 196 | case COMP_NE: t8 = (int8_t)(x != y); break; |
va009039 | 0:65f1469d6bfb | 197 | case COMP_GT: t8 = (int8_t)(x > y); break; |
va009039 | 0:65f1469d6bfb | 198 | case COMP_GE: t8 = (int8_t)(x >= y); break; |
va009039 | 0:65f1469d6bfb | 199 | case COMP_IS: t8 = (int8_t)(px == py); break; |
va009039 | 0:65f1469d6bfb | 200 | case COMP_IS_NOT: t8 = (int8_t)(px != py);break; |
va009039 | 0:65f1469d6bfb | 201 | case COMP_IN: |
va009039 | 0:65f1469d6bfb | 202 | case COMP_NOT_IN: |
va009039 | 0:65f1469d6bfb | 203 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 204 | break; |
va009039 | 0:65f1469d6bfb | 205 | |
va009039 | 0:65f1469d6bfb | 206 | default: |
va009039 | 0:65f1469d6bfb | 207 | /* Other compares are not yet supported */ |
va009039 | 0:65f1469d6bfb | 208 | PM_RAISE(retval, PM_RET_EX_SYS); |
va009039 | 0:65f1469d6bfb | 209 | break; |
va009039 | 0:65f1469d6bfb | 210 | /* *INDENT-ON* */ |
va009039 | 0:65f1469d6bfb | 211 | } |
va009039 | 0:65f1469d6bfb | 212 | *r_pobj = (t8) ? PM_TRUE : PM_FALSE; |
va009039 | 0:65f1469d6bfb | 213 | |
va009039 | 0:65f1469d6bfb | 214 | return retval; |
va009039 | 0:65f1469d6bfb | 215 | } |
va009039 | 0:65f1469d6bfb | 216 | |
va009039 | 0:65f1469d6bfb | 217 | #endif /* HAVE_FLOAT */ |