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.
int.c
00001 /* 00002 # This file is Copyright 2002 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__ 0x08 00011 00012 00013 /** 00014 * \file 00015 * \brief Integer Object Type 00016 * 00017 * Integer object type operations. 00018 */ 00019 00020 #include <limits.h> 00021 00022 #include "pm.h" 00023 00024 00025 PmReturn_t 00026 int_dup(pPmObj_t pint, pPmObj_t *r_pint) 00027 { 00028 PmReturn_t retval = PM_RET_OK; 00029 00030 /* Allocate new int */ 00031 retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint); 00032 PM_RETURN_IF_ERROR(retval); 00033 00034 /* Copy value */ 00035 OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT); 00036 ((pPmInt_t)*r_pint)->val = ((pPmInt_t)pint)->val; 00037 return retval; 00038 } 00039 00040 00041 PmReturn_t 00042 int_new(int32_t n, pPmObj_t *r_pint) 00043 { 00044 PmReturn_t retval = PM_RET_OK; 00045 00046 /* If n is 0,1,-1, return static int objects from global struct */ 00047 if (n == 0) 00048 { 00049 *r_pint = PM_ZERO; 00050 return PM_RET_OK; 00051 } 00052 if (n == 1) 00053 { 00054 *r_pint = PM_ONE; 00055 return PM_RET_OK; 00056 } 00057 if (n == -1) 00058 { 00059 *r_pint = PM_NEGONE; 00060 return PM_RET_OK; 00061 } 00062 00063 /* Else create and return new int obj */ 00064 retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint); 00065 PM_RETURN_IF_ERROR(retval); 00066 OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT); 00067 ((pPmInt_t)*r_pint)->val = n; 00068 return retval; 00069 } 00070 00071 00072 PmReturn_t 00073 int_positive(pPmObj_t pobj, pPmObj_t *r_pint) 00074 { 00075 PmReturn_t retval; 00076 00077 /* Raise TypeError if obj is not an int */ 00078 if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT) 00079 { 00080 PM_RAISE(retval, PM_RET_EX_TYPE); 00081 return retval; 00082 } 00083 00084 /* Create new int obj */ 00085 return int_new(((pPmInt_t)pobj)->val, r_pint); 00086 } 00087 00088 00089 PmReturn_t 00090 int_negative(pPmObj_t pobj, pPmObj_t *r_pint) 00091 { 00092 PmReturn_t retval; 00093 00094 /* Raise TypeError if obj is not an int */ 00095 if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT) 00096 { 00097 PM_RAISE(retval, PM_RET_EX_TYPE); 00098 return retval; 00099 } 00100 00101 /* Create new int obj */ 00102 return int_new(-((pPmInt_t)pobj)->val, r_pint); 00103 } 00104 00105 00106 PmReturn_t 00107 int_bitInvert(pPmObj_t pobj, pPmObj_t *r_pint) 00108 { 00109 PmReturn_t retval; 00110 00111 /* Raise TypeError if obj is not an int */ 00112 if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT) 00113 { 00114 PM_RAISE(retval, PM_RET_EX_TYPE); 00115 return retval; 00116 } 00117 00118 /* Create new int obj */ 00119 return int_new(~((pPmInt_t)pobj)->val, r_pint); 00120 } 00121 00122 00123 PmReturn_t 00124 int_print(pPmObj_t pint) 00125 { 00126 PmReturn_t retval = PM_RET_OK; 00127 uint8_t buf[12]; 00128 00129 C_ASSERT(pint != C_NULL); 00130 00131 /* Raise TypeError if obj is not an int */ 00132 if (OBJ_GET_TYPE(pint) != OBJ_TYPE_INT) 00133 { 00134 PM_RAISE(retval, PM_RET_EX_TYPE); 00135 return retval; 00136 } 00137 00138 retval = sli_ltoa10(((pPmInt_t)pint)->val, buf, sizeof(buf)); 00139 PM_RETURN_IF_ERROR(retval); 00140 sli_puts(buf); 00141 00142 return retval; 00143 } 00144 00145 00146 PmReturn_t 00147 int_printHex(pPmObj_t pint) 00148 { 00149 uint8_t buf[9]; 00150 PmReturn_t retval = PM_RET_OK; 00151 00152 C_ASSERT(OBJ_GET_TYPE(pint) == OBJ_TYPE_INT); 00153 00154 /* Print the integer object */ 00155 retval = sli_ltoa16(((pPmInt_t)pint)->val, buf, sizeof(buf), 1); 00156 sli_puts(buf); 00157 return retval; 00158 } 00159 00160 00161 PmReturn_t 00162 int_pow(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn) 00163 { 00164 int32_t x; 00165 int32_t y; 00166 int32_t n; 00167 PmReturn_t retval; 00168 00169 /* Raise TypeError if args aren't ints */ 00170 if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) 00171 || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT)) 00172 { 00173 PM_RAISE(retval, PM_RET_EX_TYPE); 00174 return retval; 00175 } 00176 00177 x = ((pPmInt_t)px)->val; 00178 y = ((pPmInt_t)py)->val; 00179 00180 /* Raise Value error if exponent is negative */ 00181 if (y < 0) 00182 { 00183 PM_RAISE(retval, PM_RET_EX_VAL); 00184 return retval; 00185 } 00186 00187 /* Calculate x raised to y */ 00188 n = 1; 00189 while (y > 0) 00190 { 00191 n = n * x; 00192 y--; 00193 } 00194 retval = int_new(n, r_pn); 00195 00196 return retval; 00197 } 00198 00199 00200 PmReturn_t 00201 int_divmod(pPmObj_t px, pPmObj_t py, uint8_t op, pPmObj_t *r_pxopy) 00202 { 00203 int32_t x; 00204 int32_t y; 00205 int32_t xdivy; 00206 int32_t xmody; 00207 int32_t xopy; 00208 PmReturn_t retval = PM_RET_OK; 00209 00210 /* Raise TypeError if args aren't ints */ 00211 if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) 00212 || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT)) 00213 { 00214 PM_RAISE(retval, PM_RET_EX_TYPE); 00215 return retval; 00216 } 00217 00218 x = ((pPmInt_t)px)->val; 00219 y = ((pPmInt_t)py)->val; 00220 00221 /* Raise ZeroDivisionError if denominator is zero */ 00222 if (y == 0) 00223 { 00224 PM_RAISE(retval, PM_RET_EX_ZDIV); 00225 return retval; 00226 } 00227 00228 /* Issue #167: Make overflow silent until exceptions can be caught */ 00229 /* (-sys.maxint-1)/-1 is the only overflow case. */ 00230 /* TODO: enable the overflow for Issue #169 */ 00231 /* 00232 if ((y == -1) && (op == '/') && (x < 0) 00233 && ((uint32_t)x == (0 - (uint32_t)x))) 00234 { 00235 PM_RAISE(retval, PM_RET_EX_OFLOW); 00236 return retval; 00237 } 00238 */ 00239 00240 /* Shortcut when denominator is one or negative one */ 00241 if (y == 1) 00242 { 00243 xdivy = x; 00244 xmody = 0; 00245 } 00246 else if (y == -1) 00247 { 00248 xdivy = -x; 00249 xmody = 0; 00250 } 00251 00252 else 00253 { 00254 xdivy = x / y; 00255 xmody = x - xdivy * y; 00256 00257 /* 00258 * If the remainder is non-0 and the signs of x and y differ, 00259 * C89 doesn't define whether xdivy is now the floor or the 00260 * ceiling of the infinitely precise quotient. We want the floor, 00261 * and we have it iff the remainder's sign matches y's. 00262 */ 00263 if ((xmody != 0) && ((y ^ xmody) < 0)) 00264 { 00265 xmody += y; 00266 --xdivy; 00267 C_ASSERT(xmody && ((y ^ xmody) >= 0)); 00268 } 00269 } 00270 xopy = (op == '/') ? xdivy : xmody; 00271 return int_new(xopy, r_pxopy); 00272 }
Generated on Tue Jul 12 2022 23:13:47 by
1.7.2