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/int.c@15:94ca5c8003e5, 2016-04-14 (annotated)
- Committer:
- va009039
- Date:
- Thu Apr 14 22:32:57 2016 +0000
- Revision:
- 15:94ca5c8003e5
- Parent:
- 0:65f1469d6bfb
update Nucleo-F401RE.
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 2002 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__ 0x08 |
va009039 | 0:65f1469d6bfb | 11 | |
va009039 | 0:65f1469d6bfb | 12 | |
va009039 | 0:65f1469d6bfb | 13 | /** |
va009039 | 0:65f1469d6bfb | 14 | * \file |
va009039 | 0:65f1469d6bfb | 15 | * \brief Integer Object Type |
va009039 | 0:65f1469d6bfb | 16 | * |
va009039 | 0:65f1469d6bfb | 17 | * Integer object type operations. |
va009039 | 0:65f1469d6bfb | 18 | */ |
va009039 | 0:65f1469d6bfb | 19 | |
va009039 | 0:65f1469d6bfb | 20 | #include <limits.h> |
va009039 | 0:65f1469d6bfb | 21 | |
va009039 | 0:65f1469d6bfb | 22 | #include "pm.h" |
va009039 | 0:65f1469d6bfb | 23 | |
va009039 | 0:65f1469d6bfb | 24 | |
va009039 | 0:65f1469d6bfb | 25 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 26 | int_dup(pPmObj_t pint, pPmObj_t *r_pint) |
va009039 | 0:65f1469d6bfb | 27 | { |
va009039 | 0:65f1469d6bfb | 28 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 29 | |
va009039 | 0:65f1469d6bfb | 30 | /* Allocate new int */ |
va009039 | 0:65f1469d6bfb | 31 | retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint); |
va009039 | 0:65f1469d6bfb | 32 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 33 | |
va009039 | 0:65f1469d6bfb | 34 | /* Copy value */ |
va009039 | 0:65f1469d6bfb | 35 | OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT); |
va009039 | 0:65f1469d6bfb | 36 | ((pPmInt_t)*r_pint)->val = ((pPmInt_t)pint)->val; |
va009039 | 0:65f1469d6bfb | 37 | return retval; |
va009039 | 0:65f1469d6bfb | 38 | } |
va009039 | 0:65f1469d6bfb | 39 | |
va009039 | 0:65f1469d6bfb | 40 | |
va009039 | 0:65f1469d6bfb | 41 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 42 | int_new(int32_t n, pPmObj_t *r_pint) |
va009039 | 0:65f1469d6bfb | 43 | { |
va009039 | 0:65f1469d6bfb | 44 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 45 | |
va009039 | 0:65f1469d6bfb | 46 | /* If n is 0,1,-1, return static int objects from global struct */ |
va009039 | 0:65f1469d6bfb | 47 | if (n == 0) |
va009039 | 0:65f1469d6bfb | 48 | { |
va009039 | 0:65f1469d6bfb | 49 | *r_pint = PM_ZERO; |
va009039 | 0:65f1469d6bfb | 50 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 51 | } |
va009039 | 0:65f1469d6bfb | 52 | if (n == 1) |
va009039 | 0:65f1469d6bfb | 53 | { |
va009039 | 0:65f1469d6bfb | 54 | *r_pint = PM_ONE; |
va009039 | 0:65f1469d6bfb | 55 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 56 | } |
va009039 | 0:65f1469d6bfb | 57 | if (n == -1) |
va009039 | 0:65f1469d6bfb | 58 | { |
va009039 | 0:65f1469d6bfb | 59 | *r_pint = PM_NEGONE; |
va009039 | 0:65f1469d6bfb | 60 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 61 | } |
va009039 | 0:65f1469d6bfb | 62 | |
va009039 | 0:65f1469d6bfb | 63 | /* Else create and return new int obj */ |
va009039 | 0:65f1469d6bfb | 64 | retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint); |
va009039 | 0:65f1469d6bfb | 65 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 66 | OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT); |
va009039 | 0:65f1469d6bfb | 67 | ((pPmInt_t)*r_pint)->val = n; |
va009039 | 0:65f1469d6bfb | 68 | return retval; |
va009039 | 0:65f1469d6bfb | 69 | } |
va009039 | 0:65f1469d6bfb | 70 | |
va009039 | 0:65f1469d6bfb | 71 | |
va009039 | 0:65f1469d6bfb | 72 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 73 | int_positive(pPmObj_t pobj, pPmObj_t *r_pint) |
va009039 | 0:65f1469d6bfb | 74 | { |
va009039 | 0:65f1469d6bfb | 75 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 76 | |
va009039 | 0:65f1469d6bfb | 77 | /* Raise TypeError if obj is not an int */ |
va009039 | 0:65f1469d6bfb | 78 | if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 79 | { |
va009039 | 0:65f1469d6bfb | 80 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 81 | return retval; |
va009039 | 0:65f1469d6bfb | 82 | } |
va009039 | 0:65f1469d6bfb | 83 | |
va009039 | 0:65f1469d6bfb | 84 | /* Create new int obj */ |
va009039 | 0:65f1469d6bfb | 85 | return int_new(((pPmInt_t)pobj)->val, r_pint); |
va009039 | 0:65f1469d6bfb | 86 | } |
va009039 | 0:65f1469d6bfb | 87 | |
va009039 | 0:65f1469d6bfb | 88 | |
va009039 | 0:65f1469d6bfb | 89 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 90 | int_negative(pPmObj_t pobj, pPmObj_t *r_pint) |
va009039 | 0:65f1469d6bfb | 91 | { |
va009039 | 0:65f1469d6bfb | 92 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 93 | |
va009039 | 0:65f1469d6bfb | 94 | /* Raise TypeError if obj is not an int */ |
va009039 | 0:65f1469d6bfb | 95 | if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 96 | { |
va009039 | 0:65f1469d6bfb | 97 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 98 | return retval; |
va009039 | 0:65f1469d6bfb | 99 | } |
va009039 | 0:65f1469d6bfb | 100 | |
va009039 | 0:65f1469d6bfb | 101 | /* Create new int obj */ |
va009039 | 0:65f1469d6bfb | 102 | return int_new(-((pPmInt_t)pobj)->val, r_pint); |
va009039 | 0:65f1469d6bfb | 103 | } |
va009039 | 0:65f1469d6bfb | 104 | |
va009039 | 0:65f1469d6bfb | 105 | |
va009039 | 0:65f1469d6bfb | 106 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 107 | int_bitInvert(pPmObj_t pobj, pPmObj_t *r_pint) |
va009039 | 0:65f1469d6bfb | 108 | { |
va009039 | 0:65f1469d6bfb | 109 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 110 | |
va009039 | 0:65f1469d6bfb | 111 | /* Raise TypeError if obj is not an int */ |
va009039 | 0:65f1469d6bfb | 112 | if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 113 | { |
va009039 | 0:65f1469d6bfb | 114 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 115 | return retval; |
va009039 | 0:65f1469d6bfb | 116 | } |
va009039 | 0:65f1469d6bfb | 117 | |
va009039 | 0:65f1469d6bfb | 118 | /* Create new int obj */ |
va009039 | 0:65f1469d6bfb | 119 | return int_new(~((pPmInt_t)pobj)->val, r_pint); |
va009039 | 0:65f1469d6bfb | 120 | } |
va009039 | 0:65f1469d6bfb | 121 | |
va009039 | 0:65f1469d6bfb | 122 | |
va009039 | 0:65f1469d6bfb | 123 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 124 | int_print(pPmObj_t pint) |
va009039 | 0:65f1469d6bfb | 125 | { |
va009039 | 0:65f1469d6bfb | 126 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 127 | uint8_t buf[12]; |
va009039 | 0:65f1469d6bfb | 128 | |
va009039 | 0:65f1469d6bfb | 129 | C_ASSERT(pint != C_NULL); |
va009039 | 0:65f1469d6bfb | 130 | |
va009039 | 0:65f1469d6bfb | 131 | /* Raise TypeError if obj is not an int */ |
va009039 | 0:65f1469d6bfb | 132 | if (OBJ_GET_TYPE(pint) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 133 | { |
va009039 | 0:65f1469d6bfb | 134 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 135 | return retval; |
va009039 | 0:65f1469d6bfb | 136 | } |
va009039 | 0:65f1469d6bfb | 137 | |
va009039 | 0:65f1469d6bfb | 138 | retval = sli_ltoa10(((pPmInt_t)pint)->val, buf, sizeof(buf)); |
va009039 | 0:65f1469d6bfb | 139 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 140 | sli_puts(buf); |
va009039 | 0:65f1469d6bfb | 141 | |
va009039 | 0:65f1469d6bfb | 142 | return retval; |
va009039 | 0:65f1469d6bfb | 143 | } |
va009039 | 0:65f1469d6bfb | 144 | |
va009039 | 0:65f1469d6bfb | 145 | |
va009039 | 0:65f1469d6bfb | 146 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 147 | int_printHex(pPmObj_t pint) |
va009039 | 0:65f1469d6bfb | 148 | { |
va009039 | 0:65f1469d6bfb | 149 | uint8_t buf[9]; |
va009039 | 0:65f1469d6bfb | 150 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 151 | |
va009039 | 0:65f1469d6bfb | 152 | C_ASSERT(OBJ_GET_TYPE(pint) == OBJ_TYPE_INT); |
va009039 | 0:65f1469d6bfb | 153 | |
va009039 | 0:65f1469d6bfb | 154 | /* Print the integer object */ |
va009039 | 0:65f1469d6bfb | 155 | retval = sli_ltoa16(((pPmInt_t)pint)->val, buf, sizeof(buf), 1); |
va009039 | 0:65f1469d6bfb | 156 | sli_puts(buf); |
va009039 | 0:65f1469d6bfb | 157 | return retval; |
va009039 | 0:65f1469d6bfb | 158 | } |
va009039 | 0:65f1469d6bfb | 159 | |
va009039 | 0:65f1469d6bfb | 160 | |
va009039 | 0:65f1469d6bfb | 161 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 162 | int_pow(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn) |
va009039 | 0:65f1469d6bfb | 163 | { |
va009039 | 0:65f1469d6bfb | 164 | int32_t x; |
va009039 | 0:65f1469d6bfb | 165 | int32_t y; |
va009039 | 0:65f1469d6bfb | 166 | int32_t n; |
va009039 | 0:65f1469d6bfb | 167 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 168 | |
va009039 | 0:65f1469d6bfb | 169 | /* Raise TypeError if args aren't ints */ |
va009039 | 0:65f1469d6bfb | 170 | if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 171 | || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT)) |
va009039 | 0:65f1469d6bfb | 172 | { |
va009039 | 0:65f1469d6bfb | 173 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 174 | return retval; |
va009039 | 0:65f1469d6bfb | 175 | } |
va009039 | 0:65f1469d6bfb | 176 | |
va009039 | 0:65f1469d6bfb | 177 | x = ((pPmInt_t)px)->val; |
va009039 | 0:65f1469d6bfb | 178 | y = ((pPmInt_t)py)->val; |
va009039 | 0:65f1469d6bfb | 179 | |
va009039 | 0:65f1469d6bfb | 180 | /* Raise Value error if exponent is negative */ |
va009039 | 0:65f1469d6bfb | 181 | if (y < 0) |
va009039 | 0:65f1469d6bfb | 182 | { |
va009039 | 0:65f1469d6bfb | 183 | PM_RAISE(retval, PM_RET_EX_VAL); |
va009039 | 0:65f1469d6bfb | 184 | return retval; |
va009039 | 0:65f1469d6bfb | 185 | } |
va009039 | 0:65f1469d6bfb | 186 | |
va009039 | 0:65f1469d6bfb | 187 | /* Calculate x raised to y */ |
va009039 | 0:65f1469d6bfb | 188 | n = 1; |
va009039 | 0:65f1469d6bfb | 189 | while (y > 0) |
va009039 | 0:65f1469d6bfb | 190 | { |
va009039 | 0:65f1469d6bfb | 191 | n = n * x; |
va009039 | 0:65f1469d6bfb | 192 | y--; |
va009039 | 0:65f1469d6bfb | 193 | } |
va009039 | 0:65f1469d6bfb | 194 | retval = int_new(n, r_pn); |
va009039 | 0:65f1469d6bfb | 195 | |
va009039 | 0:65f1469d6bfb | 196 | return retval; |
va009039 | 0:65f1469d6bfb | 197 | } |
va009039 | 0:65f1469d6bfb | 198 | |
va009039 | 0:65f1469d6bfb | 199 | |
va009039 | 0:65f1469d6bfb | 200 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 201 | int_divmod(pPmObj_t px, pPmObj_t py, uint8_t op, pPmObj_t *r_pxopy) |
va009039 | 0:65f1469d6bfb | 202 | { |
va009039 | 0:65f1469d6bfb | 203 | int32_t x; |
va009039 | 0:65f1469d6bfb | 204 | int32_t y; |
va009039 | 0:65f1469d6bfb | 205 | int32_t xdivy; |
va009039 | 0:65f1469d6bfb | 206 | int32_t xmody; |
va009039 | 0:65f1469d6bfb | 207 | int32_t xopy; |
va009039 | 0:65f1469d6bfb | 208 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 209 | |
va009039 | 0:65f1469d6bfb | 210 | /* Raise TypeError if args aren't ints */ |
va009039 | 0:65f1469d6bfb | 211 | if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 212 | || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT)) |
va009039 | 0:65f1469d6bfb | 213 | { |
va009039 | 0:65f1469d6bfb | 214 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 215 | return retval; |
va009039 | 0:65f1469d6bfb | 216 | } |
va009039 | 0:65f1469d6bfb | 217 | |
va009039 | 0:65f1469d6bfb | 218 | x = ((pPmInt_t)px)->val; |
va009039 | 0:65f1469d6bfb | 219 | y = ((pPmInt_t)py)->val; |
va009039 | 0:65f1469d6bfb | 220 | |
va009039 | 0:65f1469d6bfb | 221 | /* Raise ZeroDivisionError if denominator is zero */ |
va009039 | 0:65f1469d6bfb | 222 | if (y == 0) |
va009039 | 0:65f1469d6bfb | 223 | { |
va009039 | 0:65f1469d6bfb | 224 | PM_RAISE(retval, PM_RET_EX_ZDIV); |
va009039 | 0:65f1469d6bfb | 225 | return retval; |
va009039 | 0:65f1469d6bfb | 226 | } |
va009039 | 0:65f1469d6bfb | 227 | |
va009039 | 0:65f1469d6bfb | 228 | /* Issue #167: Make overflow silent until exceptions can be caught */ |
va009039 | 0:65f1469d6bfb | 229 | /* (-sys.maxint-1)/-1 is the only overflow case. */ |
va009039 | 0:65f1469d6bfb | 230 | /* TODO: enable the overflow for Issue #169 */ |
va009039 | 0:65f1469d6bfb | 231 | /* |
va009039 | 0:65f1469d6bfb | 232 | if ((y == -1) && (op == '/') && (x < 0) |
va009039 | 0:65f1469d6bfb | 233 | && ((uint32_t)x == (0 - (uint32_t)x))) |
va009039 | 0:65f1469d6bfb | 234 | { |
va009039 | 0:65f1469d6bfb | 235 | PM_RAISE(retval, PM_RET_EX_OFLOW); |
va009039 | 0:65f1469d6bfb | 236 | return retval; |
va009039 | 0:65f1469d6bfb | 237 | } |
va009039 | 0:65f1469d6bfb | 238 | */ |
va009039 | 0:65f1469d6bfb | 239 | |
va009039 | 0:65f1469d6bfb | 240 | /* Shortcut when denominator is one or negative one */ |
va009039 | 0:65f1469d6bfb | 241 | if (y == 1) |
va009039 | 0:65f1469d6bfb | 242 | { |
va009039 | 0:65f1469d6bfb | 243 | xdivy = x; |
va009039 | 0:65f1469d6bfb | 244 | xmody = 0; |
va009039 | 0:65f1469d6bfb | 245 | } |
va009039 | 0:65f1469d6bfb | 246 | else if (y == -1) |
va009039 | 0:65f1469d6bfb | 247 | { |
va009039 | 0:65f1469d6bfb | 248 | xdivy = -x; |
va009039 | 0:65f1469d6bfb | 249 | xmody = 0; |
va009039 | 0:65f1469d6bfb | 250 | } |
va009039 | 0:65f1469d6bfb | 251 | |
va009039 | 0:65f1469d6bfb | 252 | else |
va009039 | 0:65f1469d6bfb | 253 | { |
va009039 | 0:65f1469d6bfb | 254 | xdivy = x / y; |
va009039 | 0:65f1469d6bfb | 255 | xmody = x - xdivy * y; |
va009039 | 0:65f1469d6bfb | 256 | |
va009039 | 0:65f1469d6bfb | 257 | /* |
va009039 | 0:65f1469d6bfb | 258 | * If the remainder is non-0 and the signs of x and y differ, |
va009039 | 0:65f1469d6bfb | 259 | * C89 doesn't define whether xdivy is now the floor or the |
va009039 | 0:65f1469d6bfb | 260 | * ceiling of the infinitely precise quotient. We want the floor, |
va009039 | 0:65f1469d6bfb | 261 | * and we have it iff the remainder's sign matches y's. |
va009039 | 0:65f1469d6bfb | 262 | */ |
va009039 | 0:65f1469d6bfb | 263 | if ((xmody != 0) && ((y ^ xmody) < 0)) |
va009039 | 0:65f1469d6bfb | 264 | { |
va009039 | 0:65f1469d6bfb | 265 | xmody += y; |
va009039 | 0:65f1469d6bfb | 266 | --xdivy; |
va009039 | 0:65f1469d6bfb | 267 | C_ASSERT(xmody && ((y ^ xmody) >= 0)); |
va009039 | 0:65f1469d6bfb | 268 | } |
va009039 | 0:65f1469d6bfb | 269 | } |
va009039 | 0:65f1469d6bfb | 270 | xopy = (op == '/') ? xdivy : xmody; |
va009039 | 0:65f1469d6bfb | 271 | return int_new(xopy, r_pxopy); |
va009039 | 0:65f1469d6bfb | 272 | } |